implement type_name intrinsic

This commit is contained in:
hkalbasi 2023-07-14 16:52:36 +03:30
parent 274e8301c1
commit 5208bf8f55
7 changed files with 158 additions and 56 deletions

View file

@ -4,7 +4,7 @@ use hir_def::db::DefDatabase;
use crate::{
consteval::try_const_usize, db::HirDatabase, mir::pad16, test_db::TestDB, Const, ConstScalar,
Interner,
Interner, MemoryMap,
};
use super::{
@ -36,7 +36,7 @@ fn check_fail(ra_fixture: &str, error: impl FnOnce(ConstEvalError) -> bool) {
#[track_caller]
fn check_number(ra_fixture: &str, answer: i128) {
check_answer(ra_fixture, |b| {
check_answer(ra_fixture, |b, _| {
assert_eq!(
b,
&answer.to_le_bytes()[0..b.len()],
@ -47,8 +47,26 @@ fn check_number(ra_fixture: &str, answer: i128) {
}
#[track_caller]
fn check_answer(ra_fixture: &str, check: impl FnOnce(&[u8])) {
let (db, file_id) = TestDB::with_single_file(ra_fixture);
fn check_str(ra_fixture: &str, answer: &str) {
check_answer(ra_fixture, |b, mm| {
let addr = usize::from_le_bytes(b[0..b.len() / 2].try_into().unwrap());
let size = usize::from_le_bytes(b[b.len() / 2..].try_into().unwrap());
let Some(bytes) = mm.get(addr, size) else {
panic!("string data missed in the memory map");
};
assert_eq!(
bytes,
answer.as_bytes(),
"Bytes differ. In string form: actual = {}, expected = {answer}",
String::from_utf8_lossy(bytes)
);
});
}
#[track_caller]
fn check_answer(ra_fixture: &str, check: impl FnOnce(&[u8], &MemoryMap)) {
let (db, file_ids) = TestDB::with_many_files(ra_fixture);
let file_id = *file_ids.last().unwrap();
let r = match eval_goal(&db, file_id) {
Ok(t) => t,
Err(e) => {
@ -58,8 +76,8 @@ fn check_answer(ra_fixture: &str, check: impl FnOnce(&[u8])) {
};
match &r.data(Interner).value {
chalk_ir::ConstValue::Concrete(c) => match &c.interned {
ConstScalar::Bytes(b, _) => {
check(b);
ConstScalar::Bytes(b, mm) => {
check(b, mm);
}
x => panic!("Expected number but found {:?}", x),
},
@ -224,7 +242,7 @@ const GOAL: usize = {
transmute(&x)
}
"#,
|b| assert_eq!(b[0] % 8, 0),
|b, _| assert_eq!(b[0] % 8, 0),
);
check_answer(
r#"
@ -233,7 +251,7 @@ use core::mem::transmute;
static X: i64 = 12;
const GOAL: usize = transmute(&X);
"#,
|b| assert_eq!(b[0] % 8, 0),
|b, _| assert_eq!(b[0] % 8, 0),
);
}
@ -2067,6 +2085,17 @@ fn array_and_index() {
);
}
#[test]
fn string() {
check_str(
r#"
//- minicore: coerce_unsized, index, slice
const GOAL: &str = "hello";
"#,
"hello",
);
}
#[test]
fn byte_string() {
check_number(
@ -2443,6 +2472,25 @@ fn const_trait_assoc() {
"#,
32,
);
check_number(
r#"
//- /a/lib.rs crate:a
pub trait ToConst {
const VAL: usize;
}
pub const fn to_const<T: ToConst>() -> usize {
T::VAL
}
//- /main.rs crate:main deps:a
use a::{ToConst, to_const};
struct U0;
impl ToConst for U0 {
const VAL: usize = 5;
}
const GOAL: usize = to_const::<U0>();
"#,
5,
);
check_number(
r#"
struct S<T>(*mut T);

View file

@ -149,6 +149,36 @@ fn min_align_of_val() {
);
}
#[test]
fn type_name() {
check_str(
r#"
extern "rust-intrinsic" {
pub fn type_name<T: ?Sized>() -> &'static str;
}
const GOAL: &str = type_name::<i32>();
"#,
"i32",
);
check_str(
r#"
extern "rust-intrinsic" {
pub fn type_name<T: ?Sized>() -> &'static str;
}
mod mod1 {
pub mod mod2 {
pub struct Ty;
}
}
const GOAL: &str = type_name::<mod1::mod2::Ty>();
"#,
"mod1::mod2::Ty",
);
}
#[test]
fn transmute() {
check_number(