mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-27 02:06:57 +00:00
Merge commit '0113bc9388' into sync-from-ra
This commit is contained in:
parent
f43cea0878
commit
b8a3180a60
197 changed files with 3106 additions and 2007 deletions
|
|
@ -18,7 +18,7 @@ macro_rules! from_bytes {
|
|||
($ty:tt, $value:expr) => {
|
||||
($ty::from_le_bytes(match ($value).try_into() {
|
||||
Ok(it) => it,
|
||||
Err(_) => return Err(MirEvalError::TypeError("mismatched size")),
|
||||
Err(_) => return Err(MirEvalError::InternalError("mismatched size".into())),
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
|
@ -249,7 +249,9 @@ impl Evaluator<'_> {
|
|||
match alloc_fn {
|
||||
"rustc_allocator_zeroed" | "rustc_allocator" => {
|
||||
let [size, align] = args else {
|
||||
return Err(MirEvalError::TypeError("rustc_allocator args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"rustc_allocator args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let size = from_bytes!(usize, size.get(self)?);
|
||||
let align = from_bytes!(usize, align.get(self)?);
|
||||
|
|
@ -259,7 +261,9 @@ impl Evaluator<'_> {
|
|||
"rustc_deallocator" => { /* no-op for now */ }
|
||||
"rustc_reallocator" => {
|
||||
let [ptr, old_size, align, new_size] = args else {
|
||||
return Err(MirEvalError::TypeError("rustc_allocator args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"rustc_allocator args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let old_size = from_bytes!(usize, old_size.get(self)?);
|
||||
let new_size = from_bytes!(usize, new_size.get(self)?);
|
||||
|
|
@ -339,22 +343,22 @@ impl Evaluator<'_> {
|
|||
Err(MirEvalError::Panic(message))
|
||||
}
|
||||
SliceLen => {
|
||||
let arg = args
|
||||
.next()
|
||||
.ok_or(MirEvalError::TypeError("argument of <[T]>::len() is not provided"))?;
|
||||
let arg = args.next().ok_or(MirEvalError::InternalError(
|
||||
"argument of <[T]>::len() is not provided".into(),
|
||||
))?;
|
||||
let ptr_size = arg.len() / 2;
|
||||
Ok(arg[ptr_size..].into())
|
||||
}
|
||||
DropInPlace => {
|
||||
let ty =
|
||||
generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner)).ok_or(
|
||||
MirEvalError::TypeError(
|
||||
"generic argument of drop_in_place is not provided",
|
||||
MirEvalError::InternalError(
|
||||
"generic argument of drop_in_place is not provided".into(),
|
||||
),
|
||||
)?;
|
||||
let arg = args
|
||||
.next()
|
||||
.ok_or(MirEvalError::TypeError("argument of drop_in_place is not provided"))?;
|
||||
let arg = args.next().ok_or(MirEvalError::InternalError(
|
||||
"argument of drop_in_place is not provided".into(),
|
||||
))?;
|
||||
self.run_drop_glue_deep(
|
||||
ty.clone(),
|
||||
locals,
|
||||
|
|
@ -380,7 +384,9 @@ impl Evaluator<'_> {
|
|||
318 => {
|
||||
// SYS_getrandom
|
||||
let [buf, len, _flags] = args else {
|
||||
return Err(MirEvalError::TypeError("SYS_getrandom args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"SYS_getrandom args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let addr = Address::from_bytes(buf.get(self)?)?;
|
||||
let size = from_bytes!(usize, len.get(self)?);
|
||||
|
|
@ -408,7 +414,7 @@ impl Evaluator<'_> {
|
|||
match as_str {
|
||||
"memcmp" => {
|
||||
let [ptr1, ptr2, size] = args else {
|
||||
return Err(MirEvalError::TypeError("memcmp args are not provided"));
|
||||
return Err(MirEvalError::InternalError("memcmp args are not provided".into()));
|
||||
};
|
||||
let addr1 = Address::from_bytes(ptr1.get(self)?)?;
|
||||
let addr2 = Address::from_bytes(ptr2.get(self)?)?;
|
||||
|
|
@ -424,7 +430,9 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"write" => {
|
||||
let [fd, ptr, len] = args else {
|
||||
return Err(MirEvalError::TypeError("libc::write args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"libc::write args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let fd = u128::from_le_bytes(pad16(fd.get(self)?, false));
|
||||
let interval = Interval {
|
||||
|
|
@ -446,14 +454,16 @@ impl Evaluator<'_> {
|
|||
"pthread_key_create" => {
|
||||
let key = self.thread_local_storage.create_key();
|
||||
let Some(arg0) = args.first() else {
|
||||
return Err(MirEvalError::TypeError("pthread_key_create arg0 is not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"pthread_key_create arg0 is not provided".into(),
|
||||
));
|
||||
};
|
||||
let arg0_addr = Address::from_bytes(arg0.get(self)?)?;
|
||||
let key_ty = if let Some((ty, ..)) = arg0.ty.as_reference_or_ptr() {
|
||||
ty
|
||||
} else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"pthread_key_create arg0 is not a pointer",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"pthread_key_create arg0 is not a pointer".into(),
|
||||
));
|
||||
};
|
||||
let arg0_interval = Interval::new(
|
||||
|
|
@ -467,8 +477,8 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"pthread_getspecific" => {
|
||||
let Some(arg0) = args.first() else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"pthread_getspecific arg0 is not provided",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"pthread_getspecific arg0 is not provided".into(),
|
||||
));
|
||||
};
|
||||
let key = from_bytes!(usize, &pad16(arg0.get(self)?, false)[0..8]);
|
||||
|
|
@ -478,14 +488,14 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"pthread_setspecific" => {
|
||||
let Some(arg0) = args.first() else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"pthread_setspecific arg0 is not provided",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"pthread_setspecific arg0 is not provided".into(),
|
||||
));
|
||||
};
|
||||
let key = from_bytes!(usize, &pad16(arg0.get(self)?, false)[0..8]);
|
||||
let Some(arg1) = args.get(1) else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"pthread_setspecific arg1 is not provided",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"pthread_setspecific arg1 is not provided".into(),
|
||||
));
|
||||
};
|
||||
let value = from_bytes!(u128, pad16(arg1.get(self)?, false));
|
||||
|
|
@ -502,14 +512,16 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"syscall" => {
|
||||
let Some((id, rest)) = args.split_first() else {
|
||||
return Err(MirEvalError::TypeError("syscall arg1 is not provided"));
|
||||
return Err(MirEvalError::InternalError("syscall arg1 is not provided".into()));
|
||||
};
|
||||
let id = from_bytes!(i64, id.get(self)?);
|
||||
self.exec_syscall(id, rest, destination, locals, span)
|
||||
}
|
||||
"sched_getaffinity" => {
|
||||
let [_pid, _set_size, set] = args else {
|
||||
return Err(MirEvalError::TypeError("libc::write args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"libc::write args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let set = Address::from_bytes(set.get(self)?)?;
|
||||
// Only enable core 0 (we are single threaded anyway), which is bitset 0x0000001
|
||||
|
|
@ -520,7 +532,9 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"getenv" => {
|
||||
let [name] = args else {
|
||||
return Err(MirEvalError::TypeError("libc::write args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"libc::write args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let mut name_buf = vec![];
|
||||
let name = {
|
||||
|
|
@ -586,8 +600,8 @@ impl Evaluator<'_> {
|
|||
"sqrt" | "sin" | "cos" | "exp" | "exp2" | "log" | "log10" | "log2" | "fabs"
|
||||
| "floor" | "ceil" | "trunc" | "rint" | "nearbyint" | "round" | "roundeven" => {
|
||||
let [arg] = args else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"f64 intrinsic signature doesn't match fn (f64) -> f64",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"f64 intrinsic signature doesn't match fn (f64) -> f64".into(),
|
||||
));
|
||||
};
|
||||
let arg = from_bytes!(f64, arg.get(self)?);
|
||||
|
|
@ -614,8 +628,8 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"pow" | "minnum" | "maxnum" | "copysign" => {
|
||||
let [arg1, arg2] = args else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"f64 intrinsic signature doesn't match fn (f64, f64) -> f64",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"f64 intrinsic signature doesn't match fn (f64, f64) -> f64".into(),
|
||||
));
|
||||
};
|
||||
let arg1 = from_bytes!(f64, arg1.get(self)?);
|
||||
|
|
@ -630,8 +644,8 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"powi" => {
|
||||
let [arg1, arg2] = args else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"powif64 signature doesn't match fn (f64, i32) -> f64",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"powif64 signature doesn't match fn (f64, i32) -> f64".into(),
|
||||
));
|
||||
};
|
||||
let arg1 = from_bytes!(f64, arg1.get(self)?);
|
||||
|
|
@ -640,8 +654,8 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"fma" => {
|
||||
let [arg1, arg2, arg3] = args else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"fmaf64 signature doesn't match fn (f64, f64, f64) -> f64",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"fmaf64 signature doesn't match fn (f64, f64, f64) -> f64".into(),
|
||||
));
|
||||
};
|
||||
let arg1 = from_bytes!(f64, arg1.get(self)?);
|
||||
|
|
@ -658,8 +672,8 @@ impl Evaluator<'_> {
|
|||
"sqrt" | "sin" | "cos" | "exp" | "exp2" | "log" | "log10" | "log2" | "fabs"
|
||||
| "floor" | "ceil" | "trunc" | "rint" | "nearbyint" | "round" | "roundeven" => {
|
||||
let [arg] = args else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"f32 intrinsic signature doesn't match fn (f32) -> f32",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"f32 intrinsic signature doesn't match fn (f32) -> f32".into(),
|
||||
));
|
||||
};
|
||||
let arg = from_bytes!(f32, arg.get(self)?);
|
||||
|
|
@ -686,8 +700,8 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"pow" | "minnum" | "maxnum" | "copysign" => {
|
||||
let [arg1, arg2] = args else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"f32 intrinsic signature doesn't match fn (f32, f32) -> f32",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"f32 intrinsic signature doesn't match fn (f32, f32) -> f32".into(),
|
||||
));
|
||||
};
|
||||
let arg1 = from_bytes!(f32, arg1.get(self)?);
|
||||
|
|
@ -702,8 +716,8 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"powi" => {
|
||||
let [arg1, arg2] = args else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"powif32 signature doesn't match fn (f32, i32) -> f32",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"powif32 signature doesn't match fn (f32, i32) -> f32".into(),
|
||||
));
|
||||
};
|
||||
let arg1 = from_bytes!(f32, arg1.get(self)?);
|
||||
|
|
@ -712,8 +726,8 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"fma" => {
|
||||
let [arg1, arg2, arg3] = args else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"fmaf32 signature doesn't match fn (f32, f32, f32) -> f32",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"fmaf32 signature doesn't match fn (f32, f32, f32) -> f32".into(),
|
||||
));
|
||||
};
|
||||
let arg1 = from_bytes!(f32, arg1.get(self)?);
|
||||
|
|
@ -730,7 +744,9 @@ impl Evaluator<'_> {
|
|||
let Some(ty) =
|
||||
generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError("size_of generic arg is not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"size_of generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
let size = self.size_of_sized(ty, locals, "size_of arg")?;
|
||||
destination.write_from_bytes(self, &size.to_le_bytes()[0..destination.size])
|
||||
|
|
@ -739,7 +755,9 @@ impl Evaluator<'_> {
|
|||
let Some(ty) =
|
||||
generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError("align_of generic arg is not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"align_of generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
let align = self.layout(ty)?.align.abi.bytes();
|
||||
destination.write_from_bytes(self, &align.to_le_bytes()[0..destination.size])
|
||||
|
|
@ -748,10 +766,14 @@ impl Evaluator<'_> {
|
|||
let Some(ty) =
|
||||
generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError("size_of_val generic arg is not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"size_of_val generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
let [arg] = args else {
|
||||
return Err(MirEvalError::TypeError("size_of_val args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"size_of_val args are not provided".into(),
|
||||
));
|
||||
};
|
||||
if let Some((size, _)) = self.size_align_of(ty, locals)? {
|
||||
destination.write_from_bytes(self, &size.to_le_bytes())
|
||||
|
|
@ -765,12 +787,14 @@ impl Evaluator<'_> {
|
|||
let Some(ty) =
|
||||
generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"min_align_of_val generic arg is not provided",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"min_align_of_val generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
let [arg] = args else {
|
||||
return Err(MirEvalError::TypeError("min_align_of_val args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"min_align_of_val args are not provided".into(),
|
||||
));
|
||||
};
|
||||
if let Some((_, align)) = self.size_align_of(ty, locals)? {
|
||||
destination.write_from_bytes(self, &align.to_le_bytes())
|
||||
|
|
@ -784,7 +808,9 @@ impl Evaluator<'_> {
|
|||
let Some(ty) =
|
||||
generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError("type_name generic arg is not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"type_name generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
let ty_name = match ty.display_source_code(
|
||||
self.db,
|
||||
|
|
@ -808,7 +834,9 @@ impl Evaluator<'_> {
|
|||
let Some(ty) =
|
||||
generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError("size_of generic arg is not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"size_of generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
let result = !ty.clone().is_copy(self.db, locals.body.owner);
|
||||
destination.write_from_bytes(self, &[u8::from(result)])
|
||||
|
|
@ -817,14 +845,18 @@ impl Evaluator<'_> {
|
|||
// FIXME: this is wrong for const eval, it should return 2 in some
|
||||
// cases.
|
||||
let [lhs, rhs] = args else {
|
||||
return Err(MirEvalError::TypeError("wrapping_add args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"wrapping_add args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let ans = lhs.get(self)? == rhs.get(self)?;
|
||||
destination.write_from_bytes(self, &[u8::from(ans)])
|
||||
}
|
||||
"saturating_add" | "saturating_sub" => {
|
||||
let [lhs, rhs] = args else {
|
||||
return Err(MirEvalError::TypeError("saturating_add args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"saturating_add args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let lhs = u128::from_le_bytes(pad16(lhs.get(self)?, false));
|
||||
let rhs = u128::from_le_bytes(pad16(rhs.get(self)?, false));
|
||||
|
|
@ -844,7 +876,9 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"wrapping_add" | "unchecked_add" => {
|
||||
let [lhs, rhs] = args else {
|
||||
return Err(MirEvalError::TypeError("wrapping_add args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"wrapping_add args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let lhs = u128::from_le_bytes(pad16(lhs.get(self)?, false));
|
||||
let rhs = u128::from_le_bytes(pad16(rhs.get(self)?, false));
|
||||
|
|
@ -853,7 +887,9 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"ptr_offset_from_unsigned" | "ptr_offset_from" => {
|
||||
let [lhs, rhs] = args else {
|
||||
return Err(MirEvalError::TypeError("wrapping_sub args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"wrapping_sub args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let lhs = i128::from_le_bytes(pad16(lhs.get(self)?, false));
|
||||
let rhs = i128::from_le_bytes(pad16(rhs.get(self)?, false));
|
||||
|
|
@ -861,8 +897,8 @@ impl Evaluator<'_> {
|
|||
let Some(ty) =
|
||||
generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"ptr_offset_from generic arg is not provided",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"ptr_offset_from generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
let size = self.size_of_sized(ty, locals, "ptr_offset_from arg")? as i128;
|
||||
|
|
@ -871,7 +907,9 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"wrapping_sub" | "unchecked_sub" => {
|
||||
let [lhs, rhs] = args else {
|
||||
return Err(MirEvalError::TypeError("wrapping_sub args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"wrapping_sub args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let lhs = u128::from_le_bytes(pad16(lhs.get(self)?, false));
|
||||
let rhs = u128::from_le_bytes(pad16(rhs.get(self)?, false));
|
||||
|
|
@ -880,7 +918,9 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"wrapping_mul" | "unchecked_mul" => {
|
||||
let [lhs, rhs] = args else {
|
||||
return Err(MirEvalError::TypeError("wrapping_mul args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"wrapping_mul args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let lhs = u128::from_le_bytes(pad16(lhs.get(self)?, false));
|
||||
let rhs = u128::from_le_bytes(pad16(rhs.get(self)?, false));
|
||||
|
|
@ -890,7 +930,9 @@ impl Evaluator<'_> {
|
|||
"wrapping_shl" | "unchecked_shl" => {
|
||||
// FIXME: signed
|
||||
let [lhs, rhs] = args else {
|
||||
return Err(MirEvalError::TypeError("unchecked_shl args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"unchecked_shl args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let lhs = u128::from_le_bytes(pad16(lhs.get(self)?, false));
|
||||
let rhs = u128::from_le_bytes(pad16(rhs.get(self)?, false));
|
||||
|
|
@ -900,7 +942,9 @@ impl Evaluator<'_> {
|
|||
"wrapping_shr" | "unchecked_shr" => {
|
||||
// FIXME: signed
|
||||
let [lhs, rhs] = args else {
|
||||
return Err(MirEvalError::TypeError("unchecked_shr args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"unchecked_shr args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let lhs = u128::from_le_bytes(pad16(lhs.get(self)?, false));
|
||||
let rhs = u128::from_le_bytes(pad16(rhs.get(self)?, false));
|
||||
|
|
@ -910,7 +954,9 @@ impl Evaluator<'_> {
|
|||
"unchecked_rem" => {
|
||||
// FIXME: signed
|
||||
let [lhs, rhs] = args else {
|
||||
return Err(MirEvalError::TypeError("unchecked_rem args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"unchecked_rem args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let lhs = u128::from_le_bytes(pad16(lhs.get(self)?, false));
|
||||
let rhs = u128::from_le_bytes(pad16(rhs.get(self)?, false));
|
||||
|
|
@ -922,7 +968,9 @@ impl Evaluator<'_> {
|
|||
"unchecked_div" | "exact_div" => {
|
||||
// FIXME: signed
|
||||
let [lhs, rhs] = args else {
|
||||
return Err(MirEvalError::TypeError("unchecked_div args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"unchecked_div args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let lhs = u128::from_le_bytes(pad16(lhs.get(self)?, false));
|
||||
let rhs = u128::from_le_bytes(pad16(rhs.get(self)?, false));
|
||||
|
|
@ -933,7 +981,9 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" => {
|
||||
let [lhs, rhs] = args else {
|
||||
return Err(MirEvalError::TypeError("const_eval_select args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"const_eval_select args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let result_ty = TyKind::Tuple(
|
||||
2,
|
||||
|
|
@ -954,7 +1004,7 @@ impl Evaluator<'_> {
|
|||
|| ans.to_le_bytes()[op_size..].iter().any(|&it| it != 0 && it != 255);
|
||||
let is_overflow = vec![u8::from(is_overflow)];
|
||||
let layout = self.layout(&result_ty)?;
|
||||
let result = self.make_by_layout(
|
||||
let result = self.construct_with_layout(
|
||||
layout.size.bytes_usize(),
|
||||
&layout,
|
||||
None,
|
||||
|
|
@ -966,15 +1016,15 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"copy" | "copy_nonoverlapping" => {
|
||||
let [src, dst, offset] = args else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"copy_nonoverlapping args are not provided",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"copy_nonoverlapping args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let Some(ty) =
|
||||
generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"copy_nonoverlapping generic arg is not provided",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"copy_nonoverlapping generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
let src = Address::from_bytes(src.get(self)?)?;
|
||||
|
|
@ -988,18 +1038,22 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"offset" | "arith_offset" => {
|
||||
let [ptr, offset] = args else {
|
||||
return Err(MirEvalError::TypeError("offset args are not provided"));
|
||||
return Err(MirEvalError::InternalError("offset args are not provided".into()));
|
||||
};
|
||||
let ty = if name == "offset" {
|
||||
let Some(ty0) =
|
||||
generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError("offset generic arg is not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"offset generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
let Some(ty1) =
|
||||
generic_args.as_slice(Interner).get(1).and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError("offset generic arg is not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"offset generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
if !matches!(
|
||||
ty1.as_builtin(),
|
||||
|
|
@ -1008,15 +1062,15 @@ impl Evaluator<'_> {
|
|||
| BuiltinType::Uint(BuiltinUint::Usize)
|
||||
)
|
||||
) {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"offset generic arg is not usize or isize",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"offset generic arg is not usize or isize".into(),
|
||||
));
|
||||
}
|
||||
match ty0.as_raw_ptr() {
|
||||
Some((ty, _)) => ty,
|
||||
None => {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"offset generic arg is not a raw pointer",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"offset generic arg is not a raw pointer".into(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -1024,8 +1078,8 @@ impl Evaluator<'_> {
|
|||
let Some(ty) =
|
||||
generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"arith_offset generic arg is not provided",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"arith_offset generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
ty
|
||||
|
|
@ -1046,19 +1100,21 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"transmute" => {
|
||||
let [arg] = args else {
|
||||
return Err(MirEvalError::TypeError("transmute arg is not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"transmute arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
destination.write_from_interval(self, arg.interval)
|
||||
}
|
||||
"likely" | "unlikely" => {
|
||||
let [arg] = args else {
|
||||
return Err(MirEvalError::TypeError("likely arg is not provided"));
|
||||
return Err(MirEvalError::InternalError("likely arg is not provided".into()));
|
||||
};
|
||||
destination.write_from_interval(self, arg.interval)
|
||||
}
|
||||
"ctpop" => {
|
||||
let [arg] = args else {
|
||||
return Err(MirEvalError::TypeError("ctpop arg is not provided"));
|
||||
return Err(MirEvalError::InternalError("ctpop arg is not provided".into()));
|
||||
};
|
||||
let result = u128::from_le_bytes(pad16(arg.get(self)?, false)).count_ones();
|
||||
destination
|
||||
|
|
@ -1066,7 +1122,7 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"ctlz" | "ctlz_nonzero" => {
|
||||
let [arg] = args else {
|
||||
return Err(MirEvalError::TypeError("ctlz arg is not provided"));
|
||||
return Err(MirEvalError::InternalError("ctlz arg is not provided".into()));
|
||||
};
|
||||
let result =
|
||||
u128::from_le_bytes(pad16(arg.get(self)?, false)).leading_zeros() as usize;
|
||||
|
|
@ -1076,7 +1132,7 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"cttz" | "cttz_nonzero" => {
|
||||
let [arg] = args else {
|
||||
return Err(MirEvalError::TypeError("cttz arg is not provided"));
|
||||
return Err(MirEvalError::InternalError("cttz arg is not provided".into()));
|
||||
};
|
||||
let result = u128::from_le_bytes(pad16(arg.get(self)?, false)).trailing_zeros();
|
||||
destination
|
||||
|
|
@ -1084,7 +1140,9 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"rotate_left" => {
|
||||
let [lhs, rhs] = args else {
|
||||
return Err(MirEvalError::TypeError("rotate_left args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"rotate_left args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let lhs = &lhs.get(self)?[0..destination.size];
|
||||
let rhs = rhs.get(self)?[0] as u32;
|
||||
|
|
@ -1114,7 +1172,9 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"rotate_right" => {
|
||||
let [lhs, rhs] = args else {
|
||||
return Err(MirEvalError::TypeError("rotate_right args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"rotate_right args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let lhs = &lhs.get(self)?[0..destination.size];
|
||||
let rhs = rhs.get(self)?[0] as u32;
|
||||
|
|
@ -1144,13 +1204,15 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"discriminant_value" => {
|
||||
let [arg] = args else {
|
||||
return Err(MirEvalError::TypeError("discriminant_value arg is not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"discriminant_value arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
let Some(ty) =
|
||||
generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"discriminant_value generic arg is not provided",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"discriminant_value generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
let addr = Address::from_bytes(arg.get(self)?)?;
|
||||
|
|
@ -1161,11 +1223,15 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"const_eval_select" => {
|
||||
let [tuple, const_fn, _] = args else {
|
||||
return Err(MirEvalError::TypeError("const_eval_select args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"const_eval_select args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let mut args = vec![const_fn.clone()];
|
||||
let TyKind::Tuple(_, fields) = tuple.ty.kind(Interner) else {
|
||||
return Err(MirEvalError::TypeError("const_eval_select arg[0] is not a tuple"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"const_eval_select arg[0] is not a tuple".into(),
|
||||
));
|
||||
};
|
||||
let layout = self.layout(&tuple.ty)?;
|
||||
for (i, field) in fields.iter(Interner).enumerate() {
|
||||
|
|
@ -1196,21 +1262,25 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"read_via_copy" | "volatile_load" => {
|
||||
let [arg] = args else {
|
||||
return Err(MirEvalError::TypeError("read_via_copy args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"read_via_copy args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let addr = Address::from_bytes(arg.interval.get(self)?)?;
|
||||
destination.write_from_interval(self, Interval { addr, size: destination.size })
|
||||
}
|
||||
"write_via_move" => {
|
||||
let [ptr, val] = args else {
|
||||
return Err(MirEvalError::TypeError("write_via_move args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"write_via_move args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let dst = Address::from_bytes(ptr.get(self)?)?;
|
||||
let Some(ty) =
|
||||
generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"write_via_copy generic arg is not provided",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"write_via_copy generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
let size = self.size_of_sized(ty, locals, "write_via_move ptr type")?;
|
||||
|
|
@ -1219,14 +1289,18 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"write_bytes" => {
|
||||
let [dst, val, count] = args else {
|
||||
return Err(MirEvalError::TypeError("write_bytes args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"write_bytes args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let count = from_bytes!(usize, count.get(self)?);
|
||||
let val = from_bytes!(u8, val.get(self)?);
|
||||
let Some(ty) =
|
||||
generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError("write_bytes generic arg is not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"write_bytes generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
let dst = Address::from_bytes(dst.get(self)?)?;
|
||||
let size = self.size_of_sized(ty, locals, "copy_nonoverlapping ptr type")?;
|
||||
|
|
@ -1310,10 +1384,14 @@ impl Evaluator<'_> {
|
|||
|
||||
let Some(ty) = generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError("atomic intrinsic generic arg is not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"atomic intrinsic generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
let Some(arg0) = args.first() else {
|
||||
return Err(MirEvalError::TypeError("atomic intrinsic arg0 is not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"atomic intrinsic arg0 is not provided".into(),
|
||||
));
|
||||
};
|
||||
let arg0_addr = Address::from_bytes(arg0.get(self)?)?;
|
||||
let arg0_interval =
|
||||
|
|
@ -1322,7 +1400,9 @@ impl Evaluator<'_> {
|
|||
return destination.write_from_interval(self, arg0_interval);
|
||||
}
|
||||
let Some(arg1) = args.get(1) else {
|
||||
return Err(MirEvalError::TypeError("atomic intrinsic arg1 is not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"atomic intrinsic arg1 is not provided".into(),
|
||||
));
|
||||
};
|
||||
if name.starts_with("store_") {
|
||||
return arg0_interval.write_from_interval(self, arg1.interval);
|
||||
|
|
@ -1374,7 +1454,9 @@ impl Evaluator<'_> {
|
|||
return arg0_interval.write_from_bytes(self, &ans.to_le_bytes()[0..destination.size]);
|
||||
}
|
||||
let Some(arg2) = args.get(2) else {
|
||||
return Err(MirEvalError::TypeError("atomic intrinsic arg2 is not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"atomic intrinsic arg2 is not provided".into(),
|
||||
));
|
||||
};
|
||||
if name.starts_with("cxchg_") || name.starts_with("cxchgweak_") {
|
||||
let dest = if arg1.get(self)? == arg0_interval.get(self)? {
|
||||
|
|
@ -1389,7 +1471,7 @@ impl Evaluator<'_> {
|
|||
)
|
||||
.intern(Interner);
|
||||
let layout = self.layout(&result_ty)?;
|
||||
let result = self.make_by_layout(
|
||||
let result = self.construct_with_layout(
|
||||
layout.size.bytes_usize(),
|
||||
&layout,
|
||||
None,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ macro_rules! from_bytes {
|
|||
($ty:tt, $value:expr) => {
|
||||
($ty::from_le_bytes(match ($value).try_into() {
|
||||
Ok(it) => it,
|
||||
Err(_) => return Err(MirEvalError::TypeError("mismatched size")),
|
||||
Err(_) => return Err(MirEvalError::InternalError("mismatched size".into())),
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
|
@ -40,7 +40,9 @@ impl Evaluator<'_> {
|
|||
.substitute(Interner, subst);
|
||||
return Ok((fields.len(), field_ty));
|
||||
}
|
||||
return Err(MirEvalError::TypeError("simd type with no len param"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"simd type with no len param".into(),
|
||||
));
|
||||
}
|
||||
};
|
||||
match try_const_usize(self.db, len) {
|
||||
|
|
@ -48,14 +50,18 @@ impl Evaluator<'_> {
|
|||
let Some(ty) =
|
||||
subst.as_slice(Interner).first().and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError("simd type with no ty param"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"simd type with no ty param".into(),
|
||||
));
|
||||
};
|
||||
Ok((len as usize, ty.clone()))
|
||||
}
|
||||
None => Err(MirEvalError::TypeError("simd type with unevaluatable len param")),
|
||||
None => Err(MirEvalError::InternalError(
|
||||
"simd type with unevaluatable len param".into(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
_ => Err(MirEvalError::TypeError("simd type which is not a struct")),
|
||||
_ => Err(MirEvalError::InternalError("simd type which is not a struct".into())),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -71,7 +77,9 @@ impl Evaluator<'_> {
|
|||
match name {
|
||||
"and" | "or" | "xor" => {
|
||||
let [left, right] = args else {
|
||||
return Err(MirEvalError::TypeError("simd bit op args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"simd bit op args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let result = left
|
||||
.get(self)?
|
||||
|
|
@ -88,7 +96,7 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"eq" | "ne" | "lt" | "le" | "gt" | "ge" => {
|
||||
let [left, right] = args else {
|
||||
return Err(MirEvalError::TypeError("simd args are not provided"));
|
||||
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(_)));
|
||||
|
|
@ -125,7 +133,9 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"bitmask" => {
|
||||
let [op] = args else {
|
||||
return Err(MirEvalError::TypeError("simd_bitmask args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"simd_bitmask args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let (op_len, _) = self.detect_simd_ty(&op.ty)?;
|
||||
let op_count = op.interval.size / op_len;
|
||||
|
|
@ -139,18 +149,20 @@ impl Evaluator<'_> {
|
|||
}
|
||||
"shuffle" => {
|
||||
let [left, right, index] = args else {
|
||||
return Err(MirEvalError::TypeError("simd_shuffle args are not provided"));
|
||||
return Err(MirEvalError::InternalError(
|
||||
"simd_shuffle args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let TyKind::Array(_, index_len) = index.ty.kind(Interner) else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"simd_shuffle index argument has non-array type",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"simd_shuffle index argument has non-array type".into(),
|
||||
));
|
||||
};
|
||||
let index_len = match try_const_usize(self.db, index_len) {
|
||||
Some(it) => it as usize,
|
||||
None => {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"simd type with unevaluatable len param",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"simd type with unevaluatable len param".into(),
|
||||
))
|
||||
}
|
||||
};
|
||||
|
|
@ -164,8 +176,8 @@ impl Evaluator<'_> {
|
|||
let val = match vector.clone().nth(index) {
|
||||
Some(it) => it,
|
||||
None => {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"out of bound access in simd shuffle",
|
||||
return Err(MirEvalError::InternalError(
|
||||
"out of bound access in simd shuffle".into(),
|
||||
))
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue