mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
Auto merge of #15282 - HKalbasi:mir, r=HKalbasi
Give real discriminant_type to chalk
This commit is contained in:
commit
8e5f944317
13 changed files with 293 additions and 80 deletions
|
@ -26,7 +26,7 @@ pub trait WithFixture: Default + SourceDatabaseExt + 'static {
|
||||||
let fixture = ChangeFixture::parse(ra_fixture);
|
let fixture = ChangeFixture::parse(ra_fixture);
|
||||||
let mut db = Self::default();
|
let mut db = Self::default();
|
||||||
fixture.change.apply(&mut db);
|
fixture.change.apply(&mut db);
|
||||||
assert_eq!(fixture.files.len(), 1);
|
assert_eq!(fixture.files.len(), 1, "Multiple file found in the fixture");
|
||||||
(db, fixture.files[0])
|
(db, fixture.files[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -416,6 +416,44 @@ fn test_hash_expand() {
|
||||||
//- minicore: derive, hash
|
//- minicore: derive, hash
|
||||||
use core::hash::Hash;
|
use core::hash::Hash;
|
||||||
|
|
||||||
|
#[derive(Hash)]
|
||||||
|
struct Foo {
|
||||||
|
x: i32,
|
||||||
|
y: u64,
|
||||||
|
z: (i32, u64),
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
use core::hash::Hash;
|
||||||
|
|
||||||
|
#[derive(Hash)]
|
||||||
|
struct Foo {
|
||||||
|
x: i32,
|
||||||
|
y: u64,
|
||||||
|
z: (i32, u64),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl < > core::hash::Hash for Foo< > where {
|
||||||
|
fn hash<H: core::hash::Hasher>(&self , ra_expand_state: &mut H) {
|
||||||
|
match self {
|
||||||
|
Foo {
|
||||||
|
x: x, y: y, z: z,
|
||||||
|
}
|
||||||
|
=> {
|
||||||
|
x.hash(ra_expand_state);
|
||||||
|
y.hash(ra_expand_state);
|
||||||
|
z.hash(ra_expand_state);
|
||||||
|
}
|
||||||
|
,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"#]],
|
||||||
|
);
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
//- minicore: derive, hash
|
||||||
|
use core::hash::Hash;
|
||||||
|
|
||||||
#[derive(Hash)]
|
#[derive(Hash)]
|
||||||
enum Command {
|
enum Command {
|
||||||
Move { x: i32, y: i32 },
|
Move { x: i32, y: i32 },
|
||||||
|
|
|
@ -624,9 +624,14 @@ fn hash_expand(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
let check_discriminant = if matches!(&adt.shape, AdtShape::Enum { .. }) {
|
||||||
|
quote! { #krate::mem::discriminant(self).hash(ra_expand_state); }
|
||||||
|
} else {
|
||||||
|
quote! {}
|
||||||
|
};
|
||||||
quote! {
|
quote! {
|
||||||
fn hash<H: #krate::hash::Hasher>(&self, ra_expand_state: &mut H) {
|
fn hash<H: #krate::hash::Hasher>(&self, ra_expand_state: &mut H) {
|
||||||
#krate::mem::discriminant(self).hash(ra_expand_state);
|
#check_discriminant
|
||||||
match self {
|
match self {
|
||||||
##arms
|
##arms
|
||||||
}
|
}
|
||||||
|
@ -742,9 +747,6 @@ fn ord_expand(
|
||||||
// FIXME: Return expand error here
|
// FIXME: Return expand error here
|
||||||
return quote!();
|
return quote!();
|
||||||
}
|
}
|
||||||
let left = quote!(#krate::intrinsics::discriminant_value(self));
|
|
||||||
let right = quote!(#krate::intrinsics::discriminant_value(other));
|
|
||||||
|
|
||||||
let (self_patterns, other_patterns) = self_and_other_patterns(adt, &adt.name);
|
let (self_patterns, other_patterns) = self_and_other_patterns(adt, &adt.name);
|
||||||
let arms = izip!(self_patterns, other_patterns, adt.shape.field_names()).map(
|
let arms = izip!(self_patterns, other_patterns, adt.shape.field_names()).map(
|
||||||
|(pat1, pat2, fields)| {
|
|(pat1, pat2, fields)| {
|
||||||
|
@ -759,17 +761,17 @@ fn ord_expand(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let fat_arrow = fat_arrow();
|
let fat_arrow = fat_arrow();
|
||||||
let body = compare(
|
let mut body = quote! {
|
||||||
krate,
|
|
||||||
left,
|
|
||||||
right,
|
|
||||||
quote! {
|
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
##arms
|
##arms
|
||||||
_unused #fat_arrow #krate::cmp::Ordering::Equal
|
_unused #fat_arrow #krate::cmp::Ordering::Equal
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
);
|
if matches!(&adt.shape, AdtShape::Enum { .. }) {
|
||||||
|
let left = quote!(#krate::intrinsics::discriminant_value(self));
|
||||||
|
let right = quote!(#krate::intrinsics::discriminant_value(other));
|
||||||
|
body = compare(krate, left, right, body);
|
||||||
|
}
|
||||||
quote! {
|
quote! {
|
||||||
fn cmp(&self, other: &Self) -> #krate::cmp::Ordering {
|
fn cmp(&self, other: &Self) -> #krate::cmp::Ordering {
|
||||||
#body
|
#body
|
||||||
|
|
|
@ -60,9 +60,37 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
|
||||||
// FIXME: keep track of these
|
// FIXME: keep track of these
|
||||||
Arc::new(rust_ir::AdtRepr { c: false, packed: false, int: None })
|
Arc::new(rust_ir::AdtRepr { c: false, packed: false, int: None })
|
||||||
}
|
}
|
||||||
fn discriminant_type(&self, _ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> {
|
fn discriminant_type(&self, ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> {
|
||||||
// FIXME: keep track of this
|
if let chalk_ir::TyKind::Adt(id, _) = ty.kind(Interner) {
|
||||||
chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::U32)).intern(Interner)
|
if let hir_def::AdtId::EnumId(e) = id.0 {
|
||||||
|
let enum_data = self.db.enum_data(e);
|
||||||
|
let ty = enum_data.repr.unwrap_or_default().discr_type();
|
||||||
|
return chalk_ir::TyKind::Scalar(match ty {
|
||||||
|
hir_def::layout::IntegerType::Pointer(is_signed) => match is_signed {
|
||||||
|
true => chalk_ir::Scalar::Int(chalk_ir::IntTy::Isize),
|
||||||
|
false => chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize),
|
||||||
|
},
|
||||||
|
hir_def::layout::IntegerType::Fixed(size, is_signed) => match is_signed {
|
||||||
|
true => chalk_ir::Scalar::Int(match size {
|
||||||
|
hir_def::layout::Integer::I8 => chalk_ir::IntTy::I8,
|
||||||
|
hir_def::layout::Integer::I16 => chalk_ir::IntTy::I16,
|
||||||
|
hir_def::layout::Integer::I32 => chalk_ir::IntTy::I32,
|
||||||
|
hir_def::layout::Integer::I64 => chalk_ir::IntTy::I64,
|
||||||
|
hir_def::layout::Integer::I128 => chalk_ir::IntTy::I128,
|
||||||
|
}),
|
||||||
|
false => chalk_ir::Scalar::Uint(match size {
|
||||||
|
hir_def::layout::Integer::I8 => chalk_ir::UintTy::U8,
|
||||||
|
hir_def::layout::Integer::I16 => chalk_ir::UintTy::U16,
|
||||||
|
hir_def::layout::Integer::I32 => chalk_ir::UintTy::U32,
|
||||||
|
hir_def::layout::Integer::I64 => chalk_ir::UintTy::U64,
|
||||||
|
hir_def::layout::Integer::I128 => chalk_ir::UintTy::U128,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.intern(Interner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::U8)).intern(Interner)
|
||||||
}
|
}
|
||||||
fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
|
fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
|
||||||
self.db.impl_datum(self.krate, impl_id)
|
self.db.impl_datum(self.krate, impl_id)
|
||||||
|
|
|
@ -5,7 +5,7 @@ use test_utils::skip_slow_tests;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
consteval::try_const_usize, db::HirDatabase, mir::pad16, test_db::TestDB, Const, ConstScalar,
|
consteval::try_const_usize, db::HirDatabase, mir::pad16, test_db::TestDB, Const, ConstScalar,
|
||||||
Interner,
|
Interner, MemoryMap,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
@ -37,7 +37,7 @@ fn check_fail(ra_fixture: &str, error: impl FnOnce(ConstEvalError) -> bool) {
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn check_number(ra_fixture: &str, answer: i128) {
|
fn check_number(ra_fixture: &str, answer: i128) {
|
||||||
check_answer(ra_fixture, |b| {
|
check_answer(ra_fixture, |b, _| {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
b,
|
b,
|
||||||
&answer.to_le_bytes()[0..b.len()],
|
&answer.to_le_bytes()[0..b.len()],
|
||||||
|
@ -48,8 +48,26 @@ fn check_number(ra_fixture: &str, answer: i128) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn check_answer(ra_fixture: &str, check: impl FnOnce(&[u8])) {
|
fn check_str(ra_fixture: &str, answer: &str) {
|
||||||
let (db, file_id) = TestDB::with_single_file(ra_fixture);
|
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) {
|
let r = match eval_goal(&db, file_id) {
|
||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -59,8 +77,8 @@ fn check_answer(ra_fixture: &str, check: impl FnOnce(&[u8])) {
|
||||||
};
|
};
|
||||||
match &r.data(Interner).value {
|
match &r.data(Interner).value {
|
||||||
chalk_ir::ConstValue::Concrete(c) => match &c.interned {
|
chalk_ir::ConstValue::Concrete(c) => match &c.interned {
|
||||||
ConstScalar::Bytes(b, _) => {
|
ConstScalar::Bytes(b, mm) => {
|
||||||
check(b);
|
check(b, mm);
|
||||||
}
|
}
|
||||||
x => panic!("Expected number but found {:?}", x),
|
x => panic!("Expected number but found {:?}", x),
|
||||||
},
|
},
|
||||||
|
@ -225,7 +243,7 @@ const GOAL: usize = {
|
||||||
transmute(&x)
|
transmute(&x)
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
|b| assert_eq!(b[0] % 8, 0),
|
|b, _| assert_eq!(b[0] % 8, 0),
|
||||||
);
|
);
|
||||||
check_answer(
|
check_answer(
|
||||||
r#"
|
r#"
|
||||||
|
@ -234,7 +252,7 @@ use core::mem::transmute;
|
||||||
static X: i64 = 12;
|
static X: i64 = 12;
|
||||||
const GOAL: usize = transmute(&X);
|
const GOAL: usize = transmute(&X);
|
||||||
"#,
|
"#,
|
||||||
|b| assert_eq!(b[0] % 8, 0),
|
|b, _| assert_eq!(b[0] % 8, 0),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2068,6 +2086,17 @@ fn array_and_index() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn string() {
|
||||||
|
check_str(
|
||||||
|
r#"
|
||||||
|
//- minicore: coerce_unsized, index, slice
|
||||||
|
const GOAL: &str = "hello";
|
||||||
|
"#,
|
||||||
|
"hello",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn byte_string() {
|
fn byte_string() {
|
||||||
check_number(
|
check_number(
|
||||||
|
@ -2444,6 +2473,25 @@ fn const_trait_assoc() {
|
||||||
"#,
|
"#,
|
||||||
32,
|
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(
|
check_number(
|
||||||
r#"
|
r#"
|
||||||
struct S<T>(*mut T);
|
struct S<T>(*mut T);
|
||||||
|
|
|
@ -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]
|
#[test]
|
||||||
fn transmute() {
|
fn transmute() {
|
||||||
check_number(
|
check_number(
|
||||||
|
|
|
@ -464,3 +464,41 @@ fn enums_with_discriminants() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn core_mem_discriminant() {
|
||||||
|
size_and_align! {
|
||||||
|
minicore: discriminant;
|
||||||
|
struct S(i32, u64);
|
||||||
|
struct Goal(core::mem::Discriminant<S>);
|
||||||
|
}
|
||||||
|
size_and_align! {
|
||||||
|
minicore: discriminant;
|
||||||
|
#[repr(u32)]
|
||||||
|
enum S {
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
C,
|
||||||
|
}
|
||||||
|
struct Goal(core::mem::Discriminant<S>);
|
||||||
|
}
|
||||||
|
size_and_align! {
|
||||||
|
minicore: discriminant;
|
||||||
|
enum S {
|
||||||
|
A(i32),
|
||||||
|
B(i64),
|
||||||
|
C(u8),
|
||||||
|
}
|
||||||
|
struct Goal(core::mem::Discriminant<S>);
|
||||||
|
}
|
||||||
|
size_and_align! {
|
||||||
|
minicore: discriminant;
|
||||||
|
#[repr(C, u16)]
|
||||||
|
enum S {
|
||||||
|
A(i32),
|
||||||
|
B(i64) = 200,
|
||||||
|
C = 1000,
|
||||||
|
}
|
||||||
|
struct Goal(core::mem::Discriminant<S>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ use crate::{
|
||||||
infer::PointerCast,
|
infer::PointerCast,
|
||||||
layout::{Layout, LayoutError, RustcEnumVariantIdx},
|
layout::{Layout, LayoutError, RustcEnumVariantIdx},
|
||||||
mapping::from_chalk,
|
mapping::from_chalk,
|
||||||
method_resolution::is_dyn_method,
|
method_resolution::{is_dyn_method, lookup_impl_const},
|
||||||
name, static_lifetime,
|
name, static_lifetime,
|
||||||
traits::FnTrait,
|
traits::FnTrait,
|
||||||
utils::{detect_variant_from_bytes, ClosureSubst},
|
utils::{detect_variant_from_bytes, ClosureSubst},
|
||||||
|
@ -1571,8 +1571,30 @@ impl Evaluator<'_> {
|
||||||
let chalk_ir::ConstValue::Concrete(c) = &konst.data(Interner).value else {
|
let chalk_ir::ConstValue::Concrete(c) = &konst.data(Interner).value else {
|
||||||
not_supported!("evaluating non concrete constant");
|
not_supported!("evaluating non concrete constant");
|
||||||
};
|
};
|
||||||
Ok(match &c.interned {
|
let result_owner;
|
||||||
ConstScalar::Bytes(v, memory_map) => {
|
let (v, memory_map) = match &c.interned {
|
||||||
|
ConstScalar::Bytes(v, mm) => (v, mm),
|
||||||
|
ConstScalar::UnevaluatedConst(const_id, subst) => 'b: {
|
||||||
|
let mut const_id = *const_id;
|
||||||
|
let mut subst = subst.clone();
|
||||||
|
if let hir_def::GeneralConstId::ConstId(c) = const_id {
|
||||||
|
let (c, s) = lookup_impl_const(self.db, self.trait_env.clone(), c, subst);
|
||||||
|
const_id = hir_def::GeneralConstId::ConstId(c);
|
||||||
|
subst = s;
|
||||||
|
}
|
||||||
|
result_owner = self.db.const_eval(const_id.into(), subst).map_err(|e| {
|
||||||
|
let name = const_id.name(self.db.upcast());
|
||||||
|
MirEvalError::ConstEvalError(name, Box::new(e))
|
||||||
|
})?;
|
||||||
|
if let chalk_ir::ConstValue::Concrete(c) = &result_owner.data(Interner).value {
|
||||||
|
if let ConstScalar::Bytes(v, mm) = &c.interned {
|
||||||
|
break 'b (v, mm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
not_supported!("unevaluatable constant");
|
||||||
|
}
|
||||||
|
ConstScalar::Unknown => not_supported!("evaluating unknown const"),
|
||||||
|
};
|
||||||
let mut v: Cow<'_, [u8]> = Cow::Borrowed(v);
|
let mut v: Cow<'_, [u8]> = Cow::Borrowed(v);
|
||||||
let patch_map = memory_map.transform_addresses(|b, align| {
|
let patch_map = memory_map.transform_addresses(|b, align| {
|
||||||
let addr = self.heap_allocate(b.len(), align)?;
|
let addr = self.heap_allocate(b.len(), align)?;
|
||||||
|
@ -1593,13 +1615,7 @@ impl Evaluator<'_> {
|
||||||
let addr = self.heap_allocate(size, align)?;
|
let addr = self.heap_allocate(size, align)?;
|
||||||
self.write_memory(addr, &v)?;
|
self.write_memory(addr, &v)?;
|
||||||
self.patch_addresses(&patch_map, &memory_map.vtable, addr, ty, locals)?;
|
self.patch_addresses(&patch_map, &memory_map.vtable, addr, ty, locals)?;
|
||||||
Interval::new(addr, size)
|
Ok(Interval::new(addr, size))
|
||||||
}
|
|
||||||
ConstScalar::UnevaluatedConst(..) => {
|
|
||||||
not_supported!("unevaluated const present in monomorphized mir");
|
|
||||||
}
|
|
||||||
ConstScalar::Unknown => not_supported!("evaluating unknown const"),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_place(&mut self, p: &Place, locals: &Locals) -> Result<Interval> {
|
fn eval_place(&mut self, p: &Place, locals: &Locals) -> Result<Interval> {
|
||||||
|
|
|
@ -602,6 +602,26 @@ impl Evaluator<'_> {
|
||||||
destination.write_from_bytes(self, &align.to_le_bytes())
|
destination.write_from_bytes(self, &align.to_le_bytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"type_name" => {
|
||||||
|
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"));
|
||||||
|
};
|
||||||
|
let Ok(ty_name) = ty.display_source_code(
|
||||||
|
self.db,
|
||||||
|
locals.body.owner.module(self.db.upcast()),
|
||||||
|
true,
|
||||||
|
) else {
|
||||||
|
not_supported!("fail in generating type_name using source code display");
|
||||||
|
};
|
||||||
|
let len = ty_name.len();
|
||||||
|
let addr = self.heap_allocate(len, 1)?;
|
||||||
|
self.write_memory(addr, ty_name.as_bytes())?;
|
||||||
|
destination.slice(0..self.ptr_size()).write_from_bytes(self, &addr.to_bytes())?;
|
||||||
|
destination
|
||||||
|
.slice(self.ptr_size()..2 * self.ptr_size())
|
||||||
|
.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 {
|
||||||
|
|
|
@ -13,15 +13,14 @@ use chalk_ir::{
|
||||||
fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable},
|
fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable},
|
||||||
ConstData, DebruijnIndex,
|
ConstData, DebruijnIndex,
|
||||||
};
|
};
|
||||||
use hir_def::{DefWithBodyId, GeneralConstId};
|
use hir_def::DefWithBodyId;
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
consteval::unknown_const,
|
consteval::{intern_const_scalar, unknown_const},
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
from_placeholder_idx,
|
from_placeholder_idx,
|
||||||
infer::normalize,
|
infer::normalize,
|
||||||
method_resolution::lookup_impl_const,
|
|
||||||
utils::{generics, Generics},
|
utils::{generics, Generics},
|
||||||
ClosureId, Const, Interner, ProjectionTy, Substitution, TraitEnvironment, Ty, TyKind,
|
ClosureId, Const, Interner, ProjectionTy, Substitution, TraitEnvironment, Ty, TyKind,
|
||||||
};
|
};
|
||||||
|
@ -193,25 +192,12 @@ impl Filler<'_> {
|
||||||
| chalk_ir::ConstValue::Placeholder(_) => {}
|
| chalk_ir::ConstValue::Placeholder(_) => {}
|
||||||
chalk_ir::ConstValue::Concrete(cc) => match &cc.interned {
|
chalk_ir::ConstValue::Concrete(cc) => match &cc.interned {
|
||||||
crate::ConstScalar::UnevaluatedConst(const_id, subst) => {
|
crate::ConstScalar::UnevaluatedConst(const_id, subst) => {
|
||||||
let mut const_id = *const_id;
|
|
||||||
let mut subst = subst.clone();
|
let mut subst = subst.clone();
|
||||||
self.fill_subst(&mut subst)?;
|
self.fill_subst(&mut subst)?;
|
||||||
if let GeneralConstId::ConstId(c) = const_id {
|
*c = intern_const_scalar(
|
||||||
let (c, s) = lookup_impl_const(
|
crate::ConstScalar::UnevaluatedConst(*const_id, subst),
|
||||||
self.db,
|
c.data(Interner).ty.clone(),
|
||||||
self.db.trait_environment_for_body(self.owner),
|
|
||||||
c,
|
|
||||||
subst,
|
|
||||||
);
|
);
|
||||||
const_id = GeneralConstId::ConstId(c);
|
|
||||||
subst = s;
|
|
||||||
}
|
|
||||||
let result =
|
|
||||||
self.db.const_eval(const_id.into(), subst).map_err(|e| {
|
|
||||||
let name = const_id.name(self.db.upcast());
|
|
||||||
MirLowerError::ConstEvalError(name, Box::new(e))
|
|
||||||
})?;
|
|
||||||
*c = result;
|
|
||||||
}
|
}
|
||||||
crate::ConstScalar::Bytes(_, _) | crate::ConstScalar::Unknown => (),
|
crate::ConstScalar::Bytes(_, _) | crate::ConstScalar::Unknown => (),
|
||||||
},
|
},
|
||||||
|
|
|
@ -474,7 +474,7 @@ fn main() {
|
||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9288..9296,
|
range: 9289..9297,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
|
@ -487,7 +487,7 @@ fn main() {
|
||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9320..9324,
|
range: 9321..9325,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
|
@ -511,7 +511,7 @@ fn main() {
|
||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9288..9296,
|
range: 9289..9297,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
|
@ -524,7 +524,7 @@ fn main() {
|
||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9320..9324,
|
range: 9321..9325,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
|
@ -548,7 +548,7 @@ fn main() {
|
||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9288..9296,
|
range: 9289..9297,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
|
@ -561,7 +561,7 @@ fn main() {
|
||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9320..9324,
|
range: 9321..9325,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
|
|
|
@ -34,13 +34,15 @@ fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option<Strin
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
let span_formatter = |file_id, text_range: TextRange| {
|
let span_formatter = |file_id, text_range: TextRange| {
|
||||||
let line_col = db.line_index(file_id).line_col(text_range.start());
|
|
||||||
let path = &db
|
let path = &db
|
||||||
.source_root(db.file_source_root(file_id))
|
.source_root(db.file_source_root(file_id))
|
||||||
.path_for_file(&file_id)
|
.path_for_file(&file_id)
|
||||||
.map(|x| x.to_string());
|
.map(|x| x.to_string());
|
||||||
let path = path.as_deref().unwrap_or("<unknown file>");
|
let path = path.as_deref().unwrap_or("<unknown file>");
|
||||||
format!("file://{path}#{}:{}", line_col.line + 1, line_col.col)
|
match db.line_index(file_id).try_line_col(text_range.start()) {
|
||||||
|
Some(line_col) => format!("file://{path}#{}:{}", line_col.line + 1, line_col.col),
|
||||||
|
None => format!("file://{path} range {:?}", text_range),
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Some(def.eval(db, span_formatter))
|
Some(def.eval(db, span_formatter))
|
||||||
}
|
}
|
||||||
|
|
|
@ -364,6 +364,11 @@ pub mod mem {
|
||||||
pub fn size_of<T>() -> usize;
|
pub fn size_of<T>() -> usize;
|
||||||
}
|
}
|
||||||
// endregion:size_of
|
// endregion:size_of
|
||||||
|
|
||||||
|
// region:discriminant
|
||||||
|
use crate::marker::DiscriminantKind;
|
||||||
|
pub struct Discriminant<T>(<T as DiscriminantKind>::Discriminant);
|
||||||
|
// endregion:discriminant
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod ptr {
|
pub mod ptr {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue