mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
Update offset intrinsic to match 1.72
This commit is contained in:
parent
4e034d78de
commit
3864b43d28
2 changed files with 107 additions and 39 deletions
|
@ -499,24 +499,26 @@ fn offset() {
|
||||||
r#"
|
r#"
|
||||||
//- minicore: coerce_unsized, index, slice
|
//- minicore: coerce_unsized, index, slice
|
||||||
extern "rust-intrinsic" {
|
extern "rust-intrinsic" {
|
||||||
pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
|
pub fn offset<Ptr, Delta>(dst: Ptr, offset: Delta) -> Ptr;
|
||||||
|
pub fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GOAL: u8 = unsafe {
|
const GOAL: i32 = unsafe {
|
||||||
let ar: &[(u8, u8, u8)] = &[
|
let ar: &[(i32, i32, i32)] = &[
|
||||||
(10, 11, 12),
|
(10, 11, 12),
|
||||||
(20, 21, 22),
|
(20, 21, 22),
|
||||||
(30, 31, 32),
|
(30, 31, 32),
|
||||||
(40, 41, 42),
|
(40, 41, 42),
|
||||||
(50, 51, 52),
|
(50, 51, 52),
|
||||||
];
|
];
|
||||||
let ar: *const [(u8, u8, u8)] = ar;
|
let ar: *const [(i32, i32, i32)] = ar;
|
||||||
let ar = ar as *const (u8, u8, u8);
|
let ar = ar as *const (i32, i32, i32);
|
||||||
let element = *offset(ar, 2);
|
let element3 = *offset(ar, 2usize);
|
||||||
element.1
|
let element4 = *arith_offset(ar, 3);
|
||||||
|
element3.1 * 100 + element4.0
|
||||||
};
|
};
|
||||||
"#,
|
"#,
|
||||||
31,
|
3140,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
|
||||||
use chalk_ir::TyKind;
|
use chalk_ir::TyKind;
|
||||||
use hir_def::resolver::HasResolver;
|
use hir_def::{
|
||||||
|
builtin_type::{BuiltinInt, BuiltinUint},
|
||||||
|
resolver::HasResolver,
|
||||||
|
};
|
||||||
use hir_expand::mod_path::ModPath;
|
use hir_expand::mod_path::ModPath;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -300,21 +303,36 @@ impl Evaluator<'_> {
|
||||||
BeginPanic => Err(MirEvalError::Panic("<unknown-panic-payload>".to_string())),
|
BeginPanic => Err(MirEvalError::Panic("<unknown-panic-payload>".to_string())),
|
||||||
PanicFmt => {
|
PanicFmt => {
|
||||||
let message = (|| {
|
let message = (|| {
|
||||||
let resolver = self.db.crate_def_map(self.crate_id).crate_root().resolver(self.db.upcast());
|
let resolver = self
|
||||||
|
.db
|
||||||
|
.crate_def_map(self.crate_id)
|
||||||
|
.crate_root()
|
||||||
|
.resolver(self.db.upcast());
|
||||||
let Some(format_fn) = resolver.resolve_path_in_value_ns_fully(
|
let Some(format_fn) = resolver.resolve_path_in_value_ns_fully(
|
||||||
self.db.upcast(),
|
self.db.upcast(),
|
||||||
&hir_def::path::Path::from_known_path_with_no_generic(ModPath::from_segments(
|
&hir_def::path::Path::from_known_path_with_no_generic(
|
||||||
|
ModPath::from_segments(
|
||||||
hir_expand::mod_path::PathKind::Abs,
|
hir_expand::mod_path::PathKind::Abs,
|
||||||
[name![std], name![fmt], name![format]].into_iter(),
|
[name![std], name![fmt], name![format]].into_iter(),
|
||||||
)),
|
),
|
||||||
|
),
|
||||||
) else {
|
) else {
|
||||||
not_supported!("std::fmt::format not found");
|
not_supported!("std::fmt::format not found");
|
||||||
};
|
};
|
||||||
let hir_def::resolver::ValueNs::FunctionId(format_fn) = format_fn else { not_supported!("std::fmt::format is not a function") };
|
let hir_def::resolver::ValueNs::FunctionId(format_fn) = format_fn else {
|
||||||
let message_string = self.interpret_mir(self.db.mir_body(format_fn.into()).map_err(|e| MirEvalError::MirLowerError(format_fn, e))?, args.map(|x| IntervalOrOwned::Owned(x.clone())))?;
|
not_supported!("std::fmt::format is not a function")
|
||||||
let addr = Address::from_bytes(&message_string[self.ptr_size()..2 * self.ptr_size()])?;
|
};
|
||||||
|
let message_string = self.interpret_mir(
|
||||||
|
self.db
|
||||||
|
.mir_body(format_fn.into())
|
||||||
|
.map_err(|e| MirEvalError::MirLowerError(format_fn, e))?,
|
||||||
|
args.map(|x| IntervalOrOwned::Owned(x.clone())),
|
||||||
|
)?;
|
||||||
|
let addr =
|
||||||
|
Address::from_bytes(&message_string[self.ptr_size()..2 * self.ptr_size()])?;
|
||||||
let size = from_bytes!(usize, message_string[2 * self.ptr_size()..]);
|
let size = from_bytes!(usize, message_string[2 * self.ptr_size()..]);
|
||||||
Ok(std::string::String::from_utf8_lossy(self.read_memory(addr, size)?).into_owned())
|
Ok(std::string::String::from_utf8_lossy(self.read_memory(addr, size)?)
|
||||||
|
.into_owned())
|
||||||
})()
|
})()
|
||||||
.unwrap_or_else(|e| format!("Failed to render panic format args: {e:?}"));
|
.unwrap_or_else(|e| format!("Failed to render panic format args: {e:?}"));
|
||||||
Err(MirEvalError::Panic(message))
|
Err(MirEvalError::Panic(message))
|
||||||
|
@ -483,9 +501,7 @@ impl Evaluator<'_> {
|
||||||
}
|
}
|
||||||
"syscall" => {
|
"syscall" => {
|
||||||
let Some((id, rest)) = args.split_first() else {
|
let Some((id, rest)) = args.split_first() else {
|
||||||
return Err(MirEvalError::TypeError(
|
return Err(MirEvalError::TypeError("syscall arg1 is not provided"));
|
||||||
"syscall arg1 is not provided",
|
|
||||||
));
|
|
||||||
};
|
};
|
||||||
let id = from_bytes!(i64, id.get(self)?);
|
let id = from_bytes!(i64, id.get(self)?);
|
||||||
self.exec_syscall(id, rest, destination, locals, span)
|
self.exec_syscall(id, rest, destination, locals, span)
|
||||||
|
@ -710,7 +726,8 @@ impl Evaluator<'_> {
|
||||||
}
|
}
|
||||||
match name {
|
match name {
|
||||||
"size_of" => {
|
"size_of" => {
|
||||||
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
let Some(ty) =
|
||||||
|
generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
||||||
else {
|
else {
|
||||||
return Err(MirEvalError::TypeError("size_of generic arg is not provided"));
|
return Err(MirEvalError::TypeError("size_of generic arg is not provided"));
|
||||||
};
|
};
|
||||||
|
@ -718,14 +735,17 @@ impl Evaluator<'_> {
|
||||||
destination.write_from_bytes(self, &size.to_le_bytes()[0..destination.size])
|
destination.write_from_bytes(self, &size.to_le_bytes()[0..destination.size])
|
||||||
}
|
}
|
||||||
"min_align_of" | "pref_align_of" => {
|
"min_align_of" | "pref_align_of" => {
|
||||||
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner)) else {
|
let Some(ty) =
|
||||||
|
generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
||||||
|
else {
|
||||||
return Err(MirEvalError::TypeError("align_of generic arg is not provided"));
|
return Err(MirEvalError::TypeError("align_of generic arg is not provided"));
|
||||||
};
|
};
|
||||||
let align = self.layout(ty)?.align.abi.bytes();
|
let align = self.layout(ty)?.align.abi.bytes();
|
||||||
destination.write_from_bytes(self, &align.to_le_bytes()[0..destination.size])
|
destination.write_from_bytes(self, &align.to_le_bytes()[0..destination.size])
|
||||||
}
|
}
|
||||||
"size_of_val" => {
|
"size_of_val" => {
|
||||||
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
let Some(ty) =
|
||||||
|
generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
||||||
else {
|
else {
|
||||||
return Err(MirEvalError::TypeError("size_of_val generic arg is not provided"));
|
return Err(MirEvalError::TypeError("size_of_val generic arg is not provided"));
|
||||||
};
|
};
|
||||||
|
@ -741,8 +761,12 @@ impl Evaluator<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"min_align_of_val" => {
|
"min_align_of_val" => {
|
||||||
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner)) else {
|
let Some(ty) =
|
||||||
return Err(MirEvalError::TypeError("min_align_of_val generic arg is not provided"));
|
generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
||||||
|
else {
|
||||||
|
return Err(MirEvalError::TypeError(
|
||||||
|
"min_align_of_val generic arg is not provided",
|
||||||
|
));
|
||||||
};
|
};
|
||||||
let [arg] = args else {
|
let [arg] = args else {
|
||||||
return Err(MirEvalError::TypeError("min_align_of_val args are not provided"));
|
return Err(MirEvalError::TypeError("min_align_of_val args are not provided"));
|
||||||
|
@ -756,7 +780,8 @@ impl Evaluator<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"type_name" => {
|
"type_name" => {
|
||||||
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
let Some(ty) =
|
||||||
|
generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
||||||
else {
|
else {
|
||||||
return Err(MirEvalError::TypeError("type_name generic arg is not provided"));
|
return Err(MirEvalError::TypeError("type_name generic arg is not provided"));
|
||||||
};
|
};
|
||||||
|
@ -779,7 +804,8 @@ impl Evaluator<'_> {
|
||||||
.write_from_bytes(self, &len.to_le_bytes())
|
.write_from_bytes(self, &len.to_le_bytes())
|
||||||
}
|
}
|
||||||
"needs_drop" => {
|
"needs_drop" => {
|
||||||
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
let Some(ty) =
|
||||||
|
generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
||||||
else {
|
else {
|
||||||
return Err(MirEvalError::TypeError("size_of generic arg is not provided"));
|
return Err(MirEvalError::TypeError("size_of generic arg is not provided"));
|
||||||
};
|
};
|
||||||
|
@ -831,9 +857,12 @@ impl Evaluator<'_> {
|
||||||
let lhs = i128::from_le_bytes(pad16(lhs.get(self)?, false));
|
let lhs = i128::from_le_bytes(pad16(lhs.get(self)?, false));
|
||||||
let rhs = i128::from_le_bytes(pad16(rhs.get(self)?, false));
|
let rhs = i128::from_le_bytes(pad16(rhs.get(self)?, false));
|
||||||
let ans = lhs.wrapping_sub(rhs);
|
let ans = lhs.wrapping_sub(rhs);
|
||||||
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
let Some(ty) =
|
||||||
|
generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
||||||
else {
|
else {
|
||||||
return Err(MirEvalError::TypeError("ptr_offset_from generic arg is not provided"));
|
return Err(MirEvalError::TypeError(
|
||||||
|
"ptr_offset_from generic arg is not provided",
|
||||||
|
));
|
||||||
};
|
};
|
||||||
let size = self.size_of_sized(ty, locals, "ptr_offset_from arg")? as i128;
|
let size = self.size_of_sized(ty, locals, "ptr_offset_from arg")? as i128;
|
||||||
let ans = ans / size;
|
let ans = ans / size;
|
||||||
|
@ -940,7 +969,8 @@ impl Evaluator<'_> {
|
||||||
"copy_nonoverlapping args are not provided",
|
"copy_nonoverlapping args are not provided",
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
let Some(ty) =
|
||||||
|
generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
||||||
else {
|
else {
|
||||||
return Err(MirEvalError::TypeError(
|
return Err(MirEvalError::TypeError(
|
||||||
"copy_nonoverlapping generic arg is not provided",
|
"copy_nonoverlapping generic arg is not provided",
|
||||||
|
@ -959,10 +989,46 @@ impl Evaluator<'_> {
|
||||||
let [ptr, offset] = args else {
|
let [ptr, offset] = args else {
|
||||||
return Err(MirEvalError::TypeError("offset args are not provided"));
|
return Err(MirEvalError::TypeError("offset args are not provided"));
|
||||||
};
|
};
|
||||||
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
let ty = if name == "offset" {
|
||||||
|
let Some(ty0) =
|
||||||
|
generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
||||||
else {
|
else {
|
||||||
return Err(MirEvalError::TypeError("offset generic arg is not provided"));
|
return Err(MirEvalError::TypeError("offset generic arg is not provided"));
|
||||||
};
|
};
|
||||||
|
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"));
|
||||||
|
};
|
||||||
|
if !matches!(
|
||||||
|
ty1.as_builtin(),
|
||||||
|
Some(
|
||||||
|
BuiltinType::Int(BuiltinInt::Isize)
|
||||||
|
| BuiltinType::Uint(BuiltinUint::Usize)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return Err(MirEvalError::TypeError(
|
||||||
|
"offset generic arg is not usize or isize",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
match ty0.as_raw_ptr() {
|
||||||
|
Some((ty, _)) => ty,
|
||||||
|
None => {
|
||||||
|
return Err(MirEvalError::TypeError(
|
||||||
|
"offset generic arg is not a raw pointer",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let Some(ty) =
|
||||||
|
generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
||||||
|
else {
|
||||||
|
return Err(MirEvalError::TypeError(
|
||||||
|
"arith_offset generic arg is not provided",
|
||||||
|
));
|
||||||
|
};
|
||||||
|
ty
|
||||||
|
};
|
||||||
let ptr = u128::from_le_bytes(pad16(ptr.get(self)?, false));
|
let ptr = u128::from_le_bytes(pad16(ptr.get(self)?, false));
|
||||||
let offset = u128::from_le_bytes(pad16(offset.get(self)?, false));
|
let offset = u128::from_le_bytes(pad16(offset.get(self)?, false));
|
||||||
let size = self.size_of_sized(ty, locals, "offset ptr type")? as u128;
|
let size = self.size_of_sized(ty, locals, "offset ptr type")? as u128;
|
||||||
|
@ -1079,7 +1145,8 @@ impl Evaluator<'_> {
|
||||||
let [arg] = args else {
|
let [arg] = args else {
|
||||||
return Err(MirEvalError::TypeError("discriminant_value arg is not provided"));
|
return Err(MirEvalError::TypeError("discriminant_value arg is not provided"));
|
||||||
};
|
};
|
||||||
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
let Some(ty) =
|
||||||
|
generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
||||||
else {
|
else {
|
||||||
return Err(MirEvalError::TypeError(
|
return Err(MirEvalError::TypeError(
|
||||||
"discriminant_value generic arg is not provided",
|
"discriminant_value generic arg is not provided",
|
||||||
|
@ -1139,11 +1206,10 @@ impl Evaluator<'_> {
|
||||||
};
|
};
|
||||||
let count = from_bytes!(usize, count.get(self)?);
|
let count = from_bytes!(usize, count.get(self)?);
|
||||||
let val = from_bytes!(u8, val.get(self)?);
|
let val = from_bytes!(u8, val.get(self)?);
|
||||||
let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
let Some(ty) =
|
||||||
|
generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
||||||
else {
|
else {
|
||||||
return Err(MirEvalError::TypeError(
|
return Err(MirEvalError::TypeError("write_bytes generic arg is not provided"));
|
||||||
"write_bytes generic arg is not provided",
|
|
||||||
));
|
|
||||||
};
|
};
|
||||||
let dst = Address::from_bytes(dst.get(self)?)?;
|
let dst = Address::from_bytes(dst.get(self)?)?;
|
||||||
let size = self.size_of_sized(ty, locals, "copy_nonoverlapping ptr type")?;
|
let size = self.size_of_sized(ty, locals, "copy_nonoverlapping ptr type")?;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue