Auto merge of #15512 - HKalbasi:mir, r=HKalbasi
Update offset intrinsic to match 1.72 fix #15498
This commit is contained in:
commit
0a0bb777b1
2
.github/workflows/ci.yaml
vendored
2
.github/workflows/ci.yaml
vendored
@ -98,7 +98,7 @@ jobs:
|
||||
|
||||
- name: Run analysis-stats on rust std library
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: target/${{ matrix.target }}/debug/rust-analyzer analysis-stats --with-deps $(rustc --print sysroot)/lib/rustlib/src/rust/library/std
|
||||
run: RUSTC_BOOTSTRAP=1 target/${{ matrix.target }}/debug/rust-analyzer analysis-stats --with-deps $(rustc --print sysroot)/lib/rustlib/src/rust/library/std
|
||||
|
||||
# Weird targets to catch non-portable code
|
||||
rust-cross:
|
||||
|
@ -1828,7 +1828,11 @@ fn process_macro_use_extern_crate<'a>(
|
||||
let Some(paths) = attr.parse_path_comma_token_tree(db.upcast(), &hygiene) else {
|
||||
// `#[macro_use]` (without any paths) found, forget collected names and just import
|
||||
// all visible macros.
|
||||
self.def_collector.import_macros_from_extern_crate(target_crate, None, Some(extern_crate_id));
|
||||
self.def_collector.import_macros_from_extern_crate(
|
||||
target_crate,
|
||||
None,
|
||||
Some(extern_crate_id),
|
||||
);
|
||||
return;
|
||||
};
|
||||
for path in paths {
|
||||
|
@ -692,7 +692,7 @@ pub(crate) fn include_arg_to_tt(
|
||||
arg_id: MacroCallId,
|
||||
) -> Result<(triomphe::Arc<(::tt::Subtree<::tt::TokenId>, TokenMap)>, FileId), ExpandError> {
|
||||
let loc = db.lookup_intern_macro_call(arg_id);
|
||||
let Some(EagerCallInfo { arg,arg_id, .. }) = loc.eager.as_deref() else {
|
||||
let Some(EagerCallInfo { arg, arg_id, .. }) = loc.eager.as_deref() else {
|
||||
panic!("include_arg_to_tt called on non include macro call: {:?}", &loc.eager);
|
||||
};
|
||||
let path = parse_string(&arg.0)?;
|
||||
|
@ -242,7 +242,7 @@ pub(crate) fn new(db: &dyn ExpandDatabase, file_id: HirFileId) -> HygieneFrame {
|
||||
krate,
|
||||
call_site: None,
|
||||
def_site: None,
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
let def_site = info.attr_input_or_mac_def_start.map(|it| db.hygiene_frame(it.file_id));
|
||||
|
@ -499,24 +499,26 @@ fn offset() {
|
||||
r#"
|
||||
//- minicore: coerce_unsized, index, slice
|
||||
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 {
|
||||
let ar: &[(u8, u8, u8)] = &[
|
||||
const GOAL: i32 = unsafe {
|
||||
let ar: &[(i32, i32, i32)] = &[
|
||||
(10, 11, 12),
|
||||
(20, 21, 22),
|
||||
(30, 31, 32),
|
||||
(40, 41, 42),
|
||||
(50, 51, 52),
|
||||
];
|
||||
let ar: *const [(u8, u8, u8)] = ar;
|
||||
let ar = ar as *const (u8, u8, u8);
|
||||
let element = *offset(ar, 2);
|
||||
element.1
|
||||
let ar: *const [(i32, i32, i32)] = ar;
|
||||
let ar = ar as *const (i32, i32, i32);
|
||||
let element3 = *offset(ar, 2usize);
|
||||
let element4 = *arith_offset(ar, 3);
|
||||
element3.1 * 100 + element4.0
|
||||
};
|
||||
"#,
|
||||
31,
|
||||
3140,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,14 @@ pub(super) fn check(self, table: &mut InferenceTable<'_>) {
|
||||
}
|
||||
|
||||
fn check_ref_to_ptr_cast(expr_ty: Ty, cast_ty: Ty, table: &mut InferenceTable<'_>) -> bool {
|
||||
let Some((expr_inner_ty, _, _)) = expr_ty.as_reference() else { return false; };
|
||||
let Some((cast_inner_ty, _)) = cast_ty.as_raw_ptr() else { return false; };
|
||||
let TyKind::Array(expr_elt_ty, _) = expr_inner_ty.kind(Interner) else { return false; };
|
||||
let Some((expr_inner_ty, _, _)) = expr_ty.as_reference() else {
|
||||
return false;
|
||||
};
|
||||
let Some((cast_inner_ty, _)) = cast_ty.as_raw_ptr() else {
|
||||
return false;
|
||||
};
|
||||
let TyKind::Array(expr_elt_ty, _) = expr_inner_ty.kind(Interner) else {
|
||||
return false;
|
||||
};
|
||||
table.coerce(expr_elt_ty, cast_inner_ty).is_ok()
|
||||
}
|
||||
|
@ -109,7 +109,8 @@ fn layout_of_simd_ty(
|
||||
// * 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 {
|
||||
let FieldsShape::Array { count, .. } = db.layout_of_ty(f0_ty.clone(), env.clone())?.fields
|
||||
else {
|
||||
user_error!("Array with non array layout");
|
||||
};
|
||||
|
||||
|
@ -4,7 +4,10 @@
|
||||
use std::cmp;
|
||||
|
||||
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 super::*;
|
||||
@ -300,21 +303,36 @@ fn exec_lang_item(
|
||||
BeginPanic => Err(MirEvalError::Panic("<unknown-panic-payload>".to_string())),
|
||||
PanicFmt => {
|
||||
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(
|
||||
self.db.upcast(),
|
||||
&hir_def::path::Path::from_known_path_with_no_generic(ModPath::from_segments(
|
||||
hir_expand::mod_path::PathKind::Abs,
|
||||
[name![std], name![fmt], name![format]].into_iter(),
|
||||
)),
|
||||
&hir_def::path::Path::from_known_path_with_no_generic(
|
||||
ModPath::from_segments(
|
||||
hir_expand::mod_path::PathKind::Abs,
|
||||
[name![std], name![fmt], name![format]].into_iter(),
|
||||
),
|
||||
),
|
||||
) else {
|
||||
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 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 hir_def::resolver::ValueNs::FunctionId(format_fn) = format_fn else {
|
||||
not_supported!("std::fmt::format is not a function")
|
||||
};
|
||||
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()..]);
|
||||
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:?}"));
|
||||
Err(MirEvalError::Panic(message))
|
||||
@ -483,9 +501,7 @@ fn exec_extern_c(
|
||||
}
|
||||
"syscall" => {
|
||||
let Some((id, rest)) = args.split_first() else {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"syscall arg1 is not provided",
|
||||
));
|
||||
return Err(MirEvalError::TypeError("syscall arg1 is not provided"));
|
||||
};
|
||||
let id = from_bytes!(i64, id.get(self)?);
|
||||
self.exec_syscall(id, rest, destination, locals, span)
|
||||
@ -710,7 +726,8 @@ fn exec_intrinsic(
|
||||
}
|
||||
match name {
|
||||
"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 {
|
||||
return Err(MirEvalError::TypeError("size_of generic arg is not provided"));
|
||||
};
|
||||
@ -718,14 +735,17 @@ fn exec_intrinsic(
|
||||
destination.write_from_bytes(self, &size.to_le_bytes()[0..destination.size])
|
||||
}
|
||||
"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"));
|
||||
};
|
||||
let align = self.layout(ty)?.align.abi.bytes();
|
||||
destination.write_from_bytes(self, &align.to_le_bytes()[0..destination.size])
|
||||
}
|
||||
"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 {
|
||||
return Err(MirEvalError::TypeError("size_of_val generic arg is not provided"));
|
||||
};
|
||||
@ -741,8 +761,12 @@ fn exec_intrinsic(
|
||||
}
|
||||
}
|
||||
"min_align_of_val" => {
|
||||
let Some(ty) = 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 Some(ty) =
|
||||
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 {
|
||||
return Err(MirEvalError::TypeError("min_align_of_val args are not provided"));
|
||||
@ -756,7 +780,8 @@ fn exec_intrinsic(
|
||||
}
|
||||
}
|
||||
"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 {
|
||||
return Err(MirEvalError::TypeError("type_name generic arg is not provided"));
|
||||
};
|
||||
@ -779,7 +804,8 @@ fn exec_intrinsic(
|
||||
.write_from_bytes(self, &len.to_le_bytes())
|
||||
}
|
||||
"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 {
|
||||
return Err(MirEvalError::TypeError("size_of generic arg is not provided"));
|
||||
};
|
||||
@ -831,9 +857,12 @@ fn exec_intrinsic(
|
||||
let lhs = i128::from_le_bytes(pad16(lhs.get(self)?, false));
|
||||
let rhs = i128::from_le_bytes(pad16(rhs.get(self)?, false));
|
||||
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 {
|
||||
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 ans = ans / size;
|
||||
@ -940,7 +969,8 @@ fn exec_intrinsic(
|
||||
"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 {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"copy_nonoverlapping generic arg is not provided",
|
||||
@ -959,9 +989,45 @@ fn exec_intrinsic(
|
||||
let [ptr, offset] = args else {
|
||||
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))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError("offset generic arg is not provided"));
|
||||
let ty = if name == "offset" {
|
||||
let Some(ty0) =
|
||||
generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
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 offset = u128::from_le_bytes(pad16(offset.get(self)?, false));
|
||||
@ -1079,7 +1145,8 @@ fn exec_intrinsic(
|
||||
let [arg] = args else {
|
||||
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 {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"discriminant_value generic arg is not provided",
|
||||
@ -1139,11 +1206,10 @@ fn exec_intrinsic(
|
||||
};
|
||||
let count = from_bytes!(usize, count.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 {
|
||||
return Err(MirEvalError::TypeError(
|
||||
"write_bytes generic arg is not provided",
|
||||
));
|
||||
return Err(MirEvalError::TypeError("write_bytes generic arg is not provided"));
|
||||
};
|
||||
let dst = Address::from_bytes(dst.get(self)?)?;
|
||||
let size = self.size_of_sized(ty, locals, "copy_nonoverlapping ptr type")?;
|
||||
|
@ -45,7 +45,9 @@ fn detect_simd_ty(&self, ty: &Ty) -> Result<(usize, Ty)> {
|
||||
};
|
||||
match try_const_usize(self.db, len) {
|
||||
Some(len) => {
|
||||
let Some(ty) = subst.as_slice(Interner).get(0).and_then(|it| it.ty(Interner)) else {
|
||||
let Some(ty) =
|
||||
subst.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
|
||||
else {
|
||||
return Err(MirEvalError::TypeError("simd type with no ty param"));
|
||||
};
|
||||
Ok((len as usize, ty.clone()))
|
||||
|
@ -1201,7 +1201,8 @@ fn lower_expr_to_place_without_adjust(
|
||||
let Some(values) = elements
|
||||
.iter()
|
||||
.map(|it| {
|
||||
let Some((o, c)) = self.lower_expr_to_some_operand(*it, current)? else {
|
||||
let Some((o, c)) = self.lower_expr_to_some_operand(*it, current)?
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
current = c;
|
||||
@ -1259,7 +1260,8 @@ fn lower_destructing_assignment(
|
||||
*expr,
|
||||
rhs.project(ProjectionElem::TupleOrClosureField(i)),
|
||||
span,
|
||||
)? else {
|
||||
)?
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
current = c;
|
||||
@ -1268,8 +1270,7 @@ fn lower_destructing_assignment(
|
||||
}
|
||||
Expr::Underscore => Ok(Some(current)),
|
||||
_ => {
|
||||
let Some((lhs_place, current)) =
|
||||
self.lower_expr_as_place(current, lhs, false)?
|
||||
let Some((lhs_place, current)) = self.lower_expr_as_place(current, lhs, false)?
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
@ -1286,9 +1287,7 @@ fn lower_assignment(
|
||||
rhs: ExprId,
|
||||
span: MirSpan,
|
||||
) -> Result<Option<BasicBlockId>> {
|
||||
let Some((rhs_op, current)) =
|
||||
self.lower_expr_to_some_operand(rhs, current)?
|
||||
else {
|
||||
let Some((rhs_op, current)) = self.lower_expr_to_some_operand(rhs, current)? else {
|
||||
return Ok(None);
|
||||
};
|
||||
if matches!(&self.body.exprs[lhs], Expr::Underscore) {
|
||||
@ -1303,9 +1302,7 @@ fn lower_assignment(
|
||||
self.push_assignment(current, temp.clone(), rhs_op.into(), span);
|
||||
return self.lower_destructing_assignment(current, lhs, temp, span);
|
||||
}
|
||||
let Some((lhs_place, current)) =
|
||||
self.lower_expr_as_place(current, lhs, false)?
|
||||
else {
|
||||
let Some((lhs_place, current)) = self.lower_expr_as_place(current, lhs, false)? else {
|
||||
return Ok(None);
|
||||
};
|
||||
self.push_assignment(current, lhs_place, rhs_op.into(), span);
|
||||
|
Loading…
Reference in New Issue
Block a user