Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--.git-blame-ignore-revs1
-rw-r--r--crates/hir-def/src/lang_item.rs1
-rw-r--r--crates/hir-ty/src/mir/eval.rs11
-rw-r--r--crates/hir-ty/src/mir/eval/shim.rs79
-rw-r--r--crates/intern/src/symbol/symbols.rs1
5 files changed, 87 insertions, 6 deletions
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index 2ccdc8c042..651502965e 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -14,3 +14,4 @@ f247090558c9ba3c551566eae5882b7ca865225f
b2f6fd4f961fc7e4fbfdb80cae2e6065f8436f15
c48062fe2ab9a2d913d1985a6b0aec4bf936bfc1
f532576ac53ddcc666bc8d59e0b6437065e2f599
+4704881b641884de50645637108b6b6f5b68aaf9
diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs
index e83ce6dc42..166e00c9d2 100644
--- a/crates/hir-def/src/lang_item.rs
+++ b/crates/hir-def/src/lang_item.rs
@@ -501,4 +501,5 @@ language_item_table! {
String, sym::String, string, Target::Struct, GenericRequirement::None;
CStr, sym::CStr, c_str, Target::Struct, GenericRequirement::None;
+ Ordering, sym::Ordering, ordering, Target::Enum, GenericRequirement::None;
}
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 8e4c4db102..6b20522cf3 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -1644,14 +1644,15 @@ impl Evaluator<'_> {
Variants::Multiple { tag, tag_encoding, variants, .. } => {
let size = tag.size(&*self.target_data_layout).bytes_usize();
let offset = layout.fields.offset(0).bytes_usize(); // The only field on enum variants is the tag field
+ let is_signed = tag.is_signed();
match tag_encoding {
TagEncoding::Direct => {
let tag = &bytes[offset..offset + size];
- Ok(i128::from_le_bytes(pad16(tag, false)))
+ Ok(i128::from_le_bytes(pad16(tag, is_signed)))
}
TagEncoding::Niche { untagged_variant, niche_start, .. } => {
let tag = &bytes[offset..offset + size];
- let candidate_tag = i128::from_le_bytes(pad16(tag, false))
+ let candidate_tag = i128::from_le_bytes(pad16(tag, is_signed))
.wrapping_sub(*niche_start as i128)
as usize;
let idx = variants
@@ -2943,10 +2944,10 @@ pub fn render_const_using_debug_impl(
// a3 = ::core::fmt::Arguments::new_v1(a1, a2)
// FIXME: similarly, we should call function here, not directly working with memory.
let a3 = evaluator.heap_allocate(evaluator.ptr_size() * 6, evaluator.ptr_size())?;
- evaluator.write_memory(a3.offset(2 * evaluator.ptr_size()), &a1.to_bytes())?;
+ evaluator.write_memory(a3, &a1.to_bytes())?;
+ evaluator.write_memory(a3.offset(evaluator.ptr_size()), &[1])?;
+ evaluator.write_memory(a3.offset(2 * evaluator.ptr_size()), &a2.to_bytes())?;
evaluator.write_memory(a3.offset(3 * evaluator.ptr_size()), &[1])?;
- evaluator.write_memory(a3.offset(4 * evaluator.ptr_size()), &a2.to_bytes())?;
- evaluator.write_memory(a3.offset(5 * evaluator.ptr_size()), &[1])?;
let Some(ValueNs::FunctionId(format_fn)) = resolver.resolve_path_in_value_ns_fully(
db.upcast(),
&hir_def::path::Path::from_known_path_with_no_generic(path![std::fmt::format]),
diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs
index 0a78f4a5b2..38b189a517 100644
--- a/crates/hir-ty/src/mir/eval/shim.rs
+++ b/crates/hir-ty/src/mir/eval/shim.rs
@@ -1,11 +1,12 @@
//! Interpret intrinsics, lang items and `extern "C"` wellknown functions which their implementation
//! is not available.
//!
-use std::cmp;
+use std::cmp::{self, Ordering};
use chalk_ir::TyKind;
use hir_def::{
builtin_type::{BuiltinInt, BuiltinUint},
+ lang_item::LangItemTarget,
resolver::HasResolver,
};
use hir_expand::name::Name;
@@ -1317,6 +1318,82 @@ impl Evaluator<'_> {
self.write_memory_using_ref(dst, size)?.fill(val);
Ok(())
}
+ "ptr_metadata" => {
+ let [ptr] = args else {
+ return Err(MirEvalError::InternalError(
+ "ptr_metadata args are not provided".into(),
+ ));
+ };
+ let arg = ptr.interval.get(self)?.to_owned();
+ let metadata = &arg[self.ptr_size()..];
+ destination.write_from_bytes(self, metadata)?;
+ Ok(())
+ }
+ "three_way_compare" => {
+ let [lhs, rhs] = args else {
+ return Err(MirEvalError::InternalError(
+ "three_way_compare args are not provided".into(),
+ ));
+ };
+ let Some(ty) =
+ generic_args.as_slice(Interner).first().and_then(|it| it.ty(Interner))
+ else {
+ return Err(MirEvalError::InternalError(
+ "three_way_compare generic arg is not provided".into(),
+ ));
+ };
+ let signed = match ty.as_builtin().unwrap() {
+ BuiltinType::Int(_) => true,
+ BuiltinType::Uint(_) => false,
+ _ => {
+ return Err(MirEvalError::InternalError(
+ "three_way_compare expects an integral type".into(),
+ ))
+ }
+ };
+ let rhs = rhs.get(self)?;
+ let lhs = lhs.get(self)?;
+ let mut result = Ordering::Equal;
+ for (l, r) in lhs.iter().zip(rhs).rev() {
+ let it = l.cmp(r);
+ if it != Ordering::Equal {
+ result = it;
+ break;
+ }
+ }
+ if signed {
+ if let Some((&l, &r)) = lhs.iter().zip(rhs).next_back() {
+ if l != r {
+ result = (l as i8).cmp(&(r as i8));
+ }
+ }
+ }
+ if let Some(LangItemTarget::EnumId(e)) =
+ self.db.lang_item(self.crate_id, LangItem::Ordering)
+ {
+ let ty = self.db.ty(e.into());
+ let r = self
+ .compute_discriminant(ty.skip_binders().clone(), &[result as i8 as u8])?;
+ destination.write_from_bytes(self, &r.to_le_bytes()[0..destination.size])?;
+ Ok(())
+ } else {
+ Err(MirEvalError::InternalError("Ordering enum not found".into()))
+ }
+ }
+ "aggregate_raw_ptr" => {
+ let [data, meta] = args else {
+ return Err(MirEvalError::InternalError(
+ "aggregate_raw_ptr args are not provided".into(),
+ ));
+ };
+ destination.write_from_interval(self, data.interval)?;
+ Interval {
+ addr: destination.addr.offset(data.interval.size),
+ size: destination.size - data.interval.size,
+ }
+ .write_from_interval(self, meta.interval)?;
+ Ok(())
+ }
_ if needs_override => not_supported!("intrinsic {name} is not implemented"),
_ => return Ok(false),
}
diff --git a/crates/intern/src/symbol/symbols.rs b/crates/intern/src/symbol/symbols.rs
index 1b543ddf81..8df7c59aa7 100644
--- a/crates/intern/src/symbol/symbols.rs
+++ b/crates/intern/src/symbol/symbols.rs
@@ -347,6 +347,7 @@ define_symbols! {
option,
Option,
Ord,
+ Ordering,
Output,
CallRefFuture,
CallOnceFuture,