mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-08-19 18:10:25 +00:00
use rustc crates instead of copy paste
This commit is contained in:
parent
f2c9502185
commit
05906da0ec
13 changed files with 291 additions and 2083 deletions
24
Cargo.lock
generated
24
Cargo.lock
generated
|
@ -510,6 +510,8 @@ dependencies = [
|
||||||
"fst",
|
"fst",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
"hir-expand",
|
"hir-expand",
|
||||||
|
"hkalbasi-rustc-ap-rustc_abi",
|
||||||
|
"hkalbasi-rustc-ap-rustc_index",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"itertools",
|
"itertools",
|
||||||
"la-arena",
|
"la-arena",
|
||||||
|
@ -564,6 +566,7 @@ dependencies = [
|
||||||
"expect-test",
|
"expect-test",
|
||||||
"hir-def",
|
"hir-def",
|
||||||
"hir-expand",
|
"hir-expand",
|
||||||
|
"hkalbasi-rustc-ap-rustc_index",
|
||||||
"itertools",
|
"itertools",
|
||||||
"la-arena",
|
"la-arena",
|
||||||
"limit",
|
"limit",
|
||||||
|
@ -581,6 +584,27 @@ dependencies = [
|
||||||
"typed-arena",
|
"typed-arena",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hkalbasi-rustc-ap-rustc_abi"
|
||||||
|
version = "0.0.20221125"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "29c8368a30e518c0102d670d8515f7d424d875ee615ec7a7b6d29217b57a0371"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"hkalbasi-rustc-ap-rustc_index",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hkalbasi-rustc-ap-rustc_index"
|
||||||
|
version = "0.0.20221125"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c07bba80d7f6a8e1efb0f3e2115ef1eecbf97292dc8cad84e4982226b9aa12e2"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "home"
|
name = "home"
|
||||||
version = "0.5.4"
|
version = "0.5.4"
|
||||||
|
|
|
@ -33,6 +33,8 @@ base-db = { path = "../base-db", version = "0.0.0" }
|
||||||
syntax = { path = "../syntax", version = "0.0.0" }
|
syntax = { path = "../syntax", version = "0.0.0" }
|
||||||
profile = { path = "../profile", version = "0.0.0" }
|
profile = { path = "../profile", version = "0.0.0" }
|
||||||
hir-expand = { path = "../hir-expand", version = "0.0.0" }
|
hir-expand = { path = "../hir-expand", version = "0.0.0" }
|
||||||
|
rustc_abi = { version = "0.0.20221125", package = "hkalbasi-rustc-ap-rustc_abi", default-features = false }
|
||||||
|
rustc_index = { version = "0.0.20221125", package = "hkalbasi-rustc-ap-rustc_index", default-features = false }
|
||||||
mbe = { path = "../mbe", version = "0.0.0" }
|
mbe = { path = "../mbe", version = "0.0.0" }
|
||||||
cfg = { path = "../cfg", version = "0.0.0" }
|
cfg = { path = "../cfg", version = "0.0.0" }
|
||||||
tt = { path = "../tt", version = "0.0.0" }
|
tt = { path = "../tt", version = "0.0.0" }
|
||||||
|
|
|
@ -9,6 +9,7 @@ use hir_expand::{
|
||||||
HirFileId, InFile,
|
HirFileId, InFile,
|
||||||
};
|
};
|
||||||
use la_arena::{Arena, ArenaMap};
|
use la_arena::{Arena, ArenaMap};
|
||||||
|
use rustc_abi::{Integer, IntegerType};
|
||||||
use syntax::ast::{self, HasName, HasVisibility};
|
use syntax::ast::{self, HasName, HasVisibility};
|
||||||
use tt::{Delimiter, DelimiterKind, Leaf, Subtree, TokenTree};
|
use tt::{Delimiter, DelimiterKind, Leaf, Subtree, TokenTree};
|
||||||
|
|
||||||
|
@ -127,7 +128,24 @@ fn parse_repr_tt(tt: &Subtree) -> Option<ReprOptions> {
|
||||||
.map(Either::Left)
|
.map(Either::Left)
|
||||||
.or_else(|| BuiltinUint::from_suffix(repr).map(Either::Right))
|
.or_else(|| BuiltinUint::from_suffix(repr).map(Either::Right))
|
||||||
{
|
{
|
||||||
int = Some(builtin);
|
int = Some(match builtin {
|
||||||
|
Either::Left(bi) => match bi {
|
||||||
|
BuiltinInt::Isize => IntegerType::Pointer(true),
|
||||||
|
BuiltinInt::I8 => IntegerType::Fixed(Integer::I8, true),
|
||||||
|
BuiltinInt::I16 => IntegerType::Fixed(Integer::I16, true),
|
||||||
|
BuiltinInt::I32 => IntegerType::Fixed(Integer::I32, true),
|
||||||
|
BuiltinInt::I64 => IntegerType::Fixed(Integer::I64, true),
|
||||||
|
BuiltinInt::I128 => IntegerType::Fixed(Integer::I128, true),
|
||||||
|
},
|
||||||
|
Either::Right(bu) => match bu {
|
||||||
|
BuiltinUint::Usize => IntegerType::Pointer(false),
|
||||||
|
BuiltinUint::U8 => IntegerType::Fixed(Integer::I8, false),
|
||||||
|
BuiltinUint::U16 => IntegerType::Fixed(Integer::I16, false),
|
||||||
|
BuiltinUint::U32 => IntegerType::Fixed(Integer::I32, false),
|
||||||
|
BuiltinUint::U64 => IntegerType::Fixed(Integer::I64, false),
|
||||||
|
BuiltinUint::U128 => IntegerType::Fixed(Integer::I128, false),
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
ReprFlags::empty()
|
ReprFlags::empty()
|
||||||
}
|
}
|
||||||
|
@ -135,7 +153,7 @@ fn parse_repr_tt(tt: &Subtree) -> Option<ReprOptions> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(ReprOptions { int, align: max_align, pack: min_pack, flags })
|
Some(ReprOptions { int, align: max_align, pack: min_pack, flags, field_shuffle_seed: 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StructData {
|
impl StructData {
|
||||||
|
@ -276,10 +294,10 @@ impl EnumData {
|
||||||
Some(id)
|
Some(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn variant_body_type(&self) -> Either<BuiltinInt, BuiltinUint> {
|
pub fn variant_body_type(&self) -> IntegerType {
|
||||||
match self.repr {
|
match self.repr {
|
||||||
Some(ReprOptions { int: Some(builtin), .. }) => builtin,
|
Some(ReprOptions { int: Some(builtin), .. }) => builtin,
|
||||||
_ => Either::Left(BuiltinInt::Isize),
|
_ => IntegerType::Pointer(true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -25,6 +25,7 @@ chalk-derive = "0.87.0"
|
||||||
la-arena = { version = "0.3.0", path = "../../lib/la-arena" }
|
la-arena = { version = "0.3.0", path = "../../lib/la-arena" }
|
||||||
once_cell = "1.15.0"
|
once_cell = "1.15.0"
|
||||||
typed-arena = "2.0.1"
|
typed-arena = "2.0.1"
|
||||||
|
rustc_index = { version = "0.0.20221125", package = "hkalbasi-rustc-ap-rustc_index", default-features = false }
|
||||||
|
|
||||||
stdx = { path = "../stdx", version = "0.0.0" }
|
stdx = { path = "../stdx", version = "0.0.0" }
|
||||||
hir-def = { path = "../hir-def", version = "0.0.0" }
|
hir-def = { path = "../hir-def", version = "0.0.0" }
|
||||||
|
|
|
@ -19,10 +19,11 @@ use std::sync::Arc;
|
||||||
use chalk_ir::{cast::Cast, ConstValue, DebruijnIndex, Mutability, Safety, Scalar, TypeFlags};
|
use chalk_ir::{cast::Cast, ConstValue, DebruijnIndex, Mutability, Safety, Scalar, TypeFlags};
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
body::Body,
|
body::Body,
|
||||||
builtin_type::BuiltinType,
|
builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
|
||||||
data::{ConstData, StaticData},
|
data::{ConstData, StaticData},
|
||||||
expr::{BindingAnnotation, ExprId, PatId},
|
expr::{BindingAnnotation, ExprId, PatId},
|
||||||
lang_item::LangItemTarget,
|
lang_item::LangItemTarget,
|
||||||
|
layout::Integer,
|
||||||
path::{path, Path},
|
path::{path, Path},
|
||||||
resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
|
resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
|
||||||
type_ref::TypeRef,
|
type_ref::TypeRef,
|
||||||
|
@ -70,8 +71,26 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
|
||||||
DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_data(s)),
|
DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_data(s)),
|
||||||
DefWithBodyId::VariantId(v) => {
|
DefWithBodyId::VariantId(v) => {
|
||||||
ctx.return_ty = TyBuilder::builtin(match db.enum_data(v.parent).variant_body_type() {
|
ctx.return_ty = TyBuilder::builtin(match db.enum_data(v.parent).variant_body_type() {
|
||||||
Either::Left(builtin) => BuiltinType::Int(builtin),
|
hir_def::layout::IntegerType::Pointer(signed) => match signed {
|
||||||
Either::Right(builtin) => BuiltinType::Uint(builtin),
|
true => BuiltinType::Int(BuiltinInt::Isize),
|
||||||
|
false => BuiltinType::Uint(BuiltinUint::Usize),
|
||||||
|
},
|
||||||
|
hir_def::layout::IntegerType::Fixed(size, signed) => match signed {
|
||||||
|
true => BuiltinType::Int(match size {
|
||||||
|
Integer::I8 => BuiltinInt::I8,
|
||||||
|
Integer::I16 => BuiltinInt::I16,
|
||||||
|
Integer::I32 => BuiltinInt::I32,
|
||||||
|
Integer::I64 => BuiltinInt::I64,
|
||||||
|
Integer::I128 => BuiltinInt::I128,
|
||||||
|
}),
|
||||||
|
false => BuiltinType::Uint(match size {
|
||||||
|
Integer::I8 => BuiltinUint::U8,
|
||||||
|
Integer::I16 => BuiltinUint::U16,
|
||||||
|
Integer::I32 => BuiltinUint::U32,
|
||||||
|
Integer::I64 => BuiltinUint::U64,
|
||||||
|
Integer::I128 => BuiltinUint::U128,
|
||||||
|
}),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
//! Compute the binary representation of a type
|
//! Compute the binary representation of a type
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use chalk_ir::{AdtId, TyKind};
|
use chalk_ir::{AdtId, TyKind};
|
||||||
pub(self) use hir_def::layout::*;
|
pub(self) use hir_def::layout::*;
|
||||||
use hir_def::LocalFieldId;
|
use hir_def::LocalFieldId;
|
||||||
|
use stdx::never;
|
||||||
|
|
||||||
use crate::{db::HirDatabase, Interner, Substitution, Ty};
|
use crate::{db::HirDatabase, Interner, Substitution, Ty};
|
||||||
|
|
||||||
use self::adt::univariant;
|
use self::adt::struct_variant_idx;
|
||||||
pub use self::{
|
pub use self::{
|
||||||
adt::{layout_of_adt_query, layout_of_adt_recover},
|
adt::{layout_of_adt_query, layout_of_adt_recover},
|
||||||
target::current_target_data_layout_query,
|
target::current_target_data_layout_query,
|
||||||
|
@ -21,6 +24,22 @@ macro_rules! user_error {
|
||||||
mod adt;
|
mod adt;
|
||||||
mod target;
|
mod target;
|
||||||
|
|
||||||
|
struct LayoutCx<'a> {
|
||||||
|
db: &'a dyn HirDatabase,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LayoutCalculator for LayoutCx<'_> {
|
||||||
|
type TargetDataLayoutRef = Arc<TargetDataLayout>;
|
||||||
|
|
||||||
|
fn delay_bug(&self, txt: &str) {
|
||||||
|
never!("{}", txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_data_layout(&self) -> Arc<TargetDataLayout> {
|
||||||
|
self.db.current_target_data_layout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn scalar_unit(dl: &TargetDataLayout, value: Primitive) -> Scalar {
|
fn scalar_unit(dl: &TargetDataLayout, value: Primitive) -> Scalar {
|
||||||
Scalar::Initialized { value, valid_range: WrappingRange::full(value.size(dl)) }
|
Scalar::Initialized { value, valid_range: WrappingRange::full(value.size(dl)) }
|
||||||
}
|
}
|
||||||
|
@ -29,34 +48,9 @@ fn scalar(dl: &TargetDataLayout, value: Primitive) -> Layout {
|
||||||
Layout::scalar(dl, scalar_unit(dl, value))
|
Layout::scalar(dl, scalar_unit(dl, value))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scalar_pair(dl: &TargetDataLayout, a: Scalar, b: Scalar) -> Layout {
|
|
||||||
let b_align = b.align(dl);
|
|
||||||
let align = a.align(dl).max(b_align).max(dl.aggregate_align);
|
|
||||||
let b_offset = a.size(dl).align_to(b_align.abi);
|
|
||||||
let size = b_offset.checked_add(b.size(dl), dl).unwrap().align_to(align.abi);
|
|
||||||
|
|
||||||
// HACK(nox): We iter on `b` and then `a` because `max_by_key`
|
|
||||||
// returns the last maximum.
|
|
||||||
let largest_niche = Niche::from_scalar(dl, b_offset, b)
|
|
||||||
.into_iter()
|
|
||||||
.chain(Niche::from_scalar(dl, Size::ZERO, a))
|
|
||||||
.max_by_key(|niche| niche.available(dl));
|
|
||||||
|
|
||||||
Layout {
|
|
||||||
variants: Variants::Single,
|
|
||||||
fields: FieldsShape::Arbitrary {
|
|
||||||
offsets: vec![Size::ZERO, b_offset],
|
|
||||||
memory_index: vec![0, 1],
|
|
||||||
},
|
|
||||||
abi: Abi::ScalarPair(a, b),
|
|
||||||
largest_niche,
|
|
||||||
align,
|
|
||||||
size,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty) -> Result<Layout, LayoutError> {
|
pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty) -> Result<Layout, LayoutError> {
|
||||||
let dl = &*db.current_target_data_layout();
|
let dl = &*db.current_target_data_layout();
|
||||||
|
let cx = LayoutCx { db };
|
||||||
Ok(match ty.kind(Interner) {
|
Ok(match ty.kind(Interner) {
|
||||||
TyKind::Adt(AdtId(def), subst) => db.layout_of_adt(*def, subst.clone())?,
|
TyKind::Adt(AdtId(def), subst) => db.layout_of_adt(*def, subst.clone())?,
|
||||||
TyKind::Scalar(s) => match s {
|
TyKind::Scalar(s) => match s {
|
||||||
|
@ -113,14 +107,13 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty) -> Result<Layout, LayoutError
|
||||||
TyKind::Tuple(len, tys) => {
|
TyKind::Tuple(len, tys) => {
|
||||||
let kind = if *len == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized };
|
let kind = if *len == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized };
|
||||||
|
|
||||||
univariant(
|
let fields = tys
|
||||||
dl,
|
.iter(Interner)
|
||||||
&tys.iter(Interner)
|
.map(|k| layout_of_ty(db, k.assert_ty_ref(Interner)))
|
||||||
.map(|k| layout_of_ty(db, k.assert_ty_ref(Interner)))
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
.collect::<Result<Vec<_>, _>>()?,
|
let fields = fields.iter().collect::<Vec<_>>();
|
||||||
&ReprOptions::default(),
|
let fields = fields.iter().collect::<Vec<_>>();
|
||||||
kind,
|
cx.univariant(dl, &fields, &ReprOptions::default(), kind).ok_or(LayoutError::Unknown)?
|
||||||
)?
|
|
||||||
}
|
}
|
||||||
TyKind::Array(element, count) => {
|
TyKind::Array(element, count) => {
|
||||||
let count = match count.data(Interner).value {
|
let count = match count.data(Interner).value {
|
||||||
|
@ -146,7 +139,7 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty) -> Result<Layout, LayoutError
|
||||||
let largest_niche = if count != 0 { element.largest_niche } else { None };
|
let largest_niche = if count != 0 { element.largest_niche } else { None };
|
||||||
|
|
||||||
Layout {
|
Layout {
|
||||||
variants: Variants::Single,
|
variants: Variants::Single { index: struct_variant_idx() },
|
||||||
fields: FieldsShape::Array { stride: element.size, count },
|
fields: FieldsShape::Array { stride: element.size, count },
|
||||||
abi,
|
abi,
|
||||||
largest_niche,
|
largest_niche,
|
||||||
|
@ -157,7 +150,7 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty) -> Result<Layout, LayoutError
|
||||||
TyKind::Slice(element) => {
|
TyKind::Slice(element) => {
|
||||||
let element = layout_of_ty(db, element)?;
|
let element = layout_of_ty(db, element)?;
|
||||||
Layout {
|
Layout {
|
||||||
variants: Variants::Single,
|
variants: Variants::Single { index: struct_variant_idx() },
|
||||||
fields: FieldsShape::Array { stride: element.size, count: 0 },
|
fields: FieldsShape::Array { stride: element.size, count: 0 },
|
||||||
abi: Abi::Aggregate { sized: false },
|
abi: Abi::Aggregate { sized: false },
|
||||||
largest_niche: None,
|
largest_niche: None,
|
||||||
|
@ -194,13 +187,11 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty) -> Result<Layout, LayoutError
|
||||||
};
|
};
|
||||||
|
|
||||||
// Effectively a (ptr, meta) tuple.
|
// Effectively a (ptr, meta) tuple.
|
||||||
scalar_pair(dl, data_ptr, metadata)
|
cx.scalar_pair(data_ptr, metadata)
|
||||||
}
|
|
||||||
TyKind::FnDef(_, _) => {
|
|
||||||
univariant(dl, &[], &ReprOptions::default(), StructKind::AlwaysSized)?
|
|
||||||
}
|
}
|
||||||
|
TyKind::FnDef(_, _) => layout_of_unit(&cx, dl)?,
|
||||||
TyKind::Str => Layout {
|
TyKind::Str => Layout {
|
||||||
variants: Variants::Single,
|
variants: Variants::Single { index: struct_variant_idx() },
|
||||||
fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
|
fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
|
||||||
abi: Abi::Aggregate { sized: false },
|
abi: Abi::Aggregate { sized: false },
|
||||||
largest_niche: None,
|
largest_niche: None,
|
||||||
|
@ -208,7 +199,7 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty) -> Result<Layout, LayoutError
|
||||||
size: Size::ZERO,
|
size: Size::ZERO,
|
||||||
},
|
},
|
||||||
TyKind::Never => Layout {
|
TyKind::Never => Layout {
|
||||||
variants: Variants::Single,
|
variants: Variants::Single { index: struct_variant_idx() },
|
||||||
fields: FieldsShape::Primitive,
|
fields: FieldsShape::Primitive,
|
||||||
abi: Abi::Uninhabited,
|
abi: Abi::Uninhabited,
|
||||||
largest_niche: None,
|
largest_niche: None,
|
||||||
|
@ -216,7 +207,7 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty) -> Result<Layout, LayoutError
|
||||||
size: Size::ZERO,
|
size: Size::ZERO,
|
||||||
},
|
},
|
||||||
TyKind::Dyn(_) | TyKind::Foreign(_) => {
|
TyKind::Dyn(_) | TyKind::Foreign(_) => {
|
||||||
let mut unit = univariant(dl, &[], &ReprOptions::default(), StructKind::AlwaysSized)?;
|
let mut unit = layout_of_unit(&cx, dl)?;
|
||||||
match unit.abi {
|
match unit.abi {
|
||||||
Abi::Aggregate { ref mut sized } => *sized = false,
|
Abi::Aggregate { ref mut sized } => *sized = false,
|
||||||
_ => user_error!("bug"),
|
_ => user_error!("bug"),
|
||||||
|
@ -241,6 +232,16 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty) -> Result<Layout, LayoutError
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn layout_of_unit(cx: &LayoutCx<'_>, dl: &TargetDataLayout) -> Result<Layout, LayoutError> {
|
||||||
|
cx.univariant::<RustcEnumVariantIdx, &&Layout>(
|
||||||
|
&dl,
|
||||||
|
&[],
|
||||||
|
&ReprOptions::default(),
|
||||||
|
StructKind::AlwaysSized,
|
||||||
|
)
|
||||||
|
.ok_or(LayoutError::Unknown)
|
||||||
|
}
|
||||||
|
|
||||||
fn struct_tail_erasing_lifetimes(db: &dyn HirDatabase, pointee: Ty) -> Ty {
|
fn struct_tail_erasing_lifetimes(db: &dyn HirDatabase, pointee: Ty) -> Ty {
|
||||||
match pointee.kind(Interner) {
|
match pointee.kind(Interner) {
|
||||||
TyKind::Adt(AdtId(adt), subst) => match adt {
|
TyKind::Adt(AdtId(adt), subst) => match adt {
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -35,7 +35,7 @@ pub fn current_target_data_layout_query(db: &dyn HirDatabase) -> Arc<TargetDataL
|
||||||
f32_align: AbiAndPrefAlign::new(Align::from_bytes(4).unwrap()),
|
f32_align: AbiAndPrefAlign::new(Align::from_bytes(4).unwrap()),
|
||||||
f64_align: AbiAndPrefAlign::new(Align::from_bytes(8).unwrap()),
|
f64_align: AbiAndPrefAlign::new(Align::from_bytes(8).unwrap()),
|
||||||
pointer_size,
|
pointer_size,
|
||||||
pointer_align: AbiAndPrefAlign::new(Align::from_bytes(8).unwrap()),
|
pointer_align: AbiAndPrefAlign::new(Align::from_bytes(pointer_size.bytes()).unwrap()),
|
||||||
aggregate_align: AbiAndPrefAlign::new(Align::from_bytes(1).unwrap()),
|
aggregate_align: AbiAndPrefAlign::new(Align::from_bytes(1).unwrap()),
|
||||||
vector_align: vec![],
|
vector_align: vec![],
|
||||||
instruction_address_space: AddressSpace(0),
|
instruction_address_space: AddressSpace(0),
|
||||||
|
|
|
@ -49,6 +49,17 @@ fn check_fail(ra_fixture: &str, e: LayoutError) {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! size_and_align {
|
macro_rules! size_and_align {
|
||||||
|
(minicore: $($x:tt),*;$($t:tt)*) => {
|
||||||
|
{
|
||||||
|
#[allow(dead_code)]
|
||||||
|
$($t)*
|
||||||
|
check_size_and_align(
|
||||||
|
&format!("//- minicore: {}\n{}", stringify!($($x),*), stringify!($($t)*)),
|
||||||
|
::std::mem::size_of::<Goal>() as u64,
|
||||||
|
::std::mem::align_of::<Goal>() as u64,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
($($t:tt)*) => {
|
($($t:tt)*) => {
|
||||||
{
|
{
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -67,7 +78,6 @@ fn hello_world() {
|
||||||
size_and_align! {
|
size_and_align! {
|
||||||
struct Goal(i32);
|
struct Goal(i32);
|
||||||
}
|
}
|
||||||
//check_size_and_align(r#"struct Goal(i32)"#, 4, 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -148,33 +158,39 @@ fn tuple() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn non_zero() {
|
fn non_zero() {
|
||||||
check_size_and_align(
|
size_and_align! {
|
||||||
r#"
|
minicore: non_zero, option;
|
||||||
//- minicore: non_zero, option
|
use core::num::NonZeroU8;
|
||||||
use core::num::NonZeroU8;
|
struct Goal(Option<NonZeroU8>);
|
||||||
struct Goal(Option<NonZeroU8>);
|
}
|
||||||
"#,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn niche_optimization() {
|
fn niche_optimization() {
|
||||||
check_size_and_align(
|
size_and_align! {
|
||||||
r#"
|
minicore: option;
|
||||||
//- minicore: option
|
struct Goal(Option<&'static i32>);
|
||||||
struct Goal(Option<&i32>);
|
}
|
||||||
"#,
|
size_and_align! {
|
||||||
8,
|
minicore: option;
|
||||||
8,
|
struct Goal(Option<Option<bool>>);
|
||||||
);
|
}
|
||||||
check_size_and_align(
|
}
|
||||||
r#"
|
|
||||||
//- minicore: option
|
#[test]
|
||||||
struct Goal(Option<Option<bool>>);
|
fn enums_with_discriminants() {
|
||||||
"#,
|
size_and_align! {
|
||||||
1,
|
enum Goal {
|
||||||
1,
|
A = 1000,
|
||||||
);
|
B = 2000,
|
||||||
|
C = 3000,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_and_align! {
|
||||||
|
enum Goal {
|
||||||
|
A = 254,
|
||||||
|
B,
|
||||||
|
C, // implicitly becomes 256, so we need two bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -994,8 +994,30 @@ impl Enum {
|
||||||
Type::new_for_crate(
|
Type::new_for_crate(
|
||||||
self.id.lookup(db.upcast()).container.krate(),
|
self.id.lookup(db.upcast()).container.krate(),
|
||||||
TyBuilder::builtin(match db.enum_data(self.id).variant_body_type() {
|
TyBuilder::builtin(match db.enum_data(self.id).variant_body_type() {
|
||||||
Either::Left(builtin) => hir_def::builtin_type::BuiltinType::Int(builtin),
|
hir_def::layout::IntegerType::Pointer(sign) => match sign {
|
||||||
Either::Right(builtin) => hir_def::builtin_type::BuiltinType::Uint(builtin),
|
true => hir_def::builtin_type::BuiltinType::Int(
|
||||||
|
hir_def::builtin_type::BuiltinInt::Isize,
|
||||||
|
),
|
||||||
|
false => hir_def::builtin_type::BuiltinType::Uint(
|
||||||
|
hir_def::builtin_type::BuiltinUint::Usize,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
hir_def::layout::IntegerType::Fixed(i, sign) => match sign {
|
||||||
|
true => hir_def::builtin_type::BuiltinType::Int(match i {
|
||||||
|
hir_def::layout::Integer::I8 => hir_def::builtin_type::BuiltinInt::I8,
|
||||||
|
hir_def::layout::Integer::I16 => hir_def::builtin_type::BuiltinInt::I16,
|
||||||
|
hir_def::layout::Integer::I32 => hir_def::builtin_type::BuiltinInt::I32,
|
||||||
|
hir_def::layout::Integer::I64 => hir_def::builtin_type::BuiltinInt::I64,
|
||||||
|
hir_def::layout::Integer::I128 => hir_def::builtin_type::BuiltinInt::I128,
|
||||||
|
}),
|
||||||
|
false => hir_def::builtin_type::BuiltinType::Uint(match i {
|
||||||
|
hir_def::layout::Integer::I8 => hir_def::builtin_type::BuiltinUint::U8,
|
||||||
|
hir_def::layout::Integer::I16 => hir_def::builtin_type::BuiltinUint::U16,
|
||||||
|
hir_def::layout::Integer::I32 => hir_def::builtin_type::BuiltinUint::U32,
|
||||||
|
hir_def::layout::Integer::I64 => hir_def::builtin_type::BuiltinUint::U64,
|
||||||
|
hir_def::layout::Integer::I128 => hir_def::builtin_type::BuiltinUint::U128,
|
||||||
|
}),
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,7 @@ use std::fmt::Display;
|
||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir::{
|
use hir::{
|
||||||
db::HirDatabase, Adt, AsAssocItem, AttributeTemplate, HasAttrs, HasSource, HirDisplay,
|
Adt, AsAssocItem, AttributeTemplate, HasAttrs, HasSource, HirDisplay, Semantics, TypeInfo,
|
||||||
Semantics, TypeInfo,
|
|
||||||
};
|
};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
base_db::SourceDatabase,
|
base_db::SourceDatabase,
|
||||||
|
@ -398,7 +397,7 @@ pub(super) fn definition(
|
||||||
let offset = match var_def {
|
let offset = match var_def {
|
||||||
hir::VariantDef::Struct(s) => {
|
hir::VariantDef::Struct(s) => {
|
||||||
let layout = Adt::from(s).layout(db).ok()?;
|
let layout = Adt::from(s).layout(db).ok()?;
|
||||||
layout.fields.offset(id, &db.current_target_data_layout())
|
layout.fields.offset(id)
|
||||||
}
|
}
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
|
@ -537,7 +537,7 @@ struct Foo { fiel$0d_a: u8, field_b: i32, field_c: i16 }
|
||||||
```
|
```
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
field_a: u8 // size = 1, align = 1, offset = 6
|
field_a: u8 // size = 1, align = 1, offset = 4
|
||||||
```
|
```
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue