mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 22:01:37 +00:00
Remove UserError from LayoutError
This commit is contained in:
parent
e844784d8d
commit
b74015512d
4 changed files with 42 additions and 32 deletions
|
@ -1,5 +1,7 @@
|
||||||
//! Compute the binary representation of a type
|
//! Compute the binary representation of a type
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy};
|
use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy};
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
layout::{
|
layout::{
|
||||||
|
@ -26,12 +28,6 @@ pub use self::{
|
||||||
target::target_data_layout_query,
|
target::target_data_layout_query,
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! user_error {
|
|
||||||
($it: expr) => {
|
|
||||||
return Err(LayoutError::UserError(format!($it).into()))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
mod adt;
|
mod adt;
|
||||||
mod target;
|
mod target;
|
||||||
|
|
||||||
|
@ -73,13 +69,38 @@ pub type Variants = hir_def::layout::Variants<RustcFieldIdx, RustcEnumVariantIdx
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum LayoutError {
|
pub enum LayoutError {
|
||||||
UserError(Box<str>),
|
HasErrorConst,
|
||||||
|
HasErrorType,
|
||||||
|
HasPlaceholder,
|
||||||
|
InvalidSimdType,
|
||||||
|
NotImplemented,
|
||||||
|
RecursiveTypeWithoutIndirection,
|
||||||
SizeOverflow,
|
SizeOverflow,
|
||||||
TargetLayoutNotAvailable,
|
TargetLayoutNotAvailable,
|
||||||
HasPlaceholder,
|
|
||||||
HasErrorType,
|
|
||||||
NotImplemented,
|
|
||||||
Unknown,
|
Unknown,
|
||||||
|
UserReprTooSmall,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for LayoutError {}
|
||||||
|
impl fmt::Display for LayoutError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
LayoutError::HasErrorConst => write!(f, "type contains an unevaluatable const"),
|
||||||
|
LayoutError::HasErrorType => write!(f, "type contains an error"),
|
||||||
|
LayoutError::HasPlaceholder => write!(f, "type contains placeholders"),
|
||||||
|
LayoutError::InvalidSimdType => write!(f, "invalid simd type definition"),
|
||||||
|
LayoutError::NotImplemented => write!(f, "not implemented"),
|
||||||
|
LayoutError::RecursiveTypeWithoutIndirection => {
|
||||||
|
write!(f, "recursive type without indirection")
|
||||||
|
}
|
||||||
|
LayoutError::SizeOverflow => write!(f, "size overflow"),
|
||||||
|
LayoutError::TargetLayoutNotAvailable => write!(f, "target layout not available"),
|
||||||
|
LayoutError::Unknown => write!(f, "unknown"),
|
||||||
|
LayoutError::UserReprTooSmall => {
|
||||||
|
write!(f, "the `#[repr]` hint is too small to hold the discriminants of the enum")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LayoutCx<'a> {
|
struct LayoutCx<'a> {
|
||||||
|
@ -118,9 +139,7 @@ fn layout_of_simd_ty(
|
||||||
|
|
||||||
let f0_ty = match fields.iter().next() {
|
let f0_ty = match fields.iter().next() {
|
||||||
Some(it) => it.1.clone().substitute(Interner, subst),
|
Some(it) => it.1.clone().substitute(Interner, subst),
|
||||||
None => {
|
None => return Err(LayoutError::InvalidSimdType),
|
||||||
user_error!("simd type with zero fields");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// The element type and number of elements of the SIMD vector
|
// The element type and number of elements of the SIMD vector
|
||||||
|
@ -134,7 +153,7 @@ fn layout_of_simd_ty(
|
||||||
// Extract the number of elements from the layout of the array field:
|
// 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
|
let FieldsShape::Array { count, .. } = db.layout_of_ty(f0_ty.clone(), env.clone())?.fields
|
||||||
else {
|
else {
|
||||||
user_error!("Array with non array layout");
|
return Err(LayoutError::Unknown);
|
||||||
};
|
};
|
||||||
|
|
||||||
(e_ty.clone(), count, true)
|
(e_ty.clone(), count, true)
|
||||||
|
@ -146,7 +165,7 @@ fn layout_of_simd_ty(
|
||||||
// Compute the ABI of the element type:
|
// Compute the ABI of the element type:
|
||||||
let e_ly = db.layout_of_ty(e_ty, env.clone())?;
|
let e_ly = db.layout_of_ty(e_ty, env.clone())?;
|
||||||
let Abi::Scalar(e_abi) = e_ly.abi else {
|
let Abi::Scalar(e_abi) = e_ly.abi else {
|
||||||
user_error!("simd type with inner non scalar type");
|
return Err(LayoutError::Unknown);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Compute the size and alignment of the vector:
|
// Compute the size and alignment of the vector:
|
||||||
|
@ -259,9 +278,7 @@ pub fn layout_of_ty_query(
|
||||||
cx.univariant(dl, &fields, &ReprOptions::default(), kind).ok_or(LayoutError::Unknown)?
|
cx.univariant(dl, &fields, &ReprOptions::default(), kind).ok_or(LayoutError::Unknown)?
|
||||||
}
|
}
|
||||||
TyKind::Array(element, count) => {
|
TyKind::Array(element, count) => {
|
||||||
let count = try_const_usize(db, &count).ok_or(LayoutError::UserError(Box::from(
|
let count = try_const_usize(db, &count).ok_or(LayoutError::HasErrorConst)? as u64;
|
||||||
"unevaluated or mistyped const generic parameter",
|
|
||||||
)))? as u64;
|
|
||||||
let element = db.layout_of_ty(element.clone(), trait_env.clone())?;
|
let element = db.layout_of_ty(element.clone(), trait_env.clone())?;
|
||||||
let size = element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow)?;
|
let size = element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow)?;
|
||||||
|
|
||||||
|
@ -352,7 +369,7 @@ pub fn layout_of_ty_query(
|
||||||
let mut unit = layout_of_unit(&cx, dl)?;
|
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"),
|
_ => return Err(LayoutError::Unknown),
|
||||||
}
|
}
|
||||||
unit
|
unit
|
||||||
}
|
}
|
||||||
|
@ -418,7 +435,7 @@ pub fn layout_of_ty_recover(
|
||||||
_: &Ty,
|
_: &Ty,
|
||||||
_: &Arc<TraitEnvironment>,
|
_: &Arc<TraitEnvironment>,
|
||||||
) -> Result<Arc<Layout>, LayoutError> {
|
) -> Result<Arc<Layout>, LayoutError> {
|
||||||
user_error!("infinite sized recursive type");
|
Err(LayoutError::RecursiveTypeWithoutIndirection)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout_of_unit(cx: &LayoutCx<'_>, dl: &TargetDataLayout) -> Result<Layout, LayoutError> {
|
fn layout_of_unit(cx: &LayoutCx<'_>, dl: &TargetDataLayout) -> Result<Layout, LayoutError> {
|
||||||
|
|
|
@ -145,7 +145,7 @@ pub fn layout_of_adt_recover(
|
||||||
_: &Substitution,
|
_: &Substitution,
|
||||||
_: &Arc<TraitEnvironment>,
|
_: &Arc<TraitEnvironment>,
|
||||||
) -> Result<Arc<Layout>, LayoutError> {
|
) -> Result<Arc<Layout>, LayoutError> {
|
||||||
user_error!("infinite sized recursive type");
|
Err(LayoutError::RecursiveTypeWithoutIndirection)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds the appropriate Integer type and signedness for the given
|
/// Finds the appropriate Integer type and signedness for the given
|
||||||
|
@ -169,11 +169,7 @@ fn repr_discr(
|
||||||
let discr = Integer::from_attr(dl, ity);
|
let discr = Integer::from_attr(dl, ity);
|
||||||
let fit = if ity.is_signed() { signed_fit } else { unsigned_fit };
|
let fit = if ity.is_signed() { signed_fit } else { unsigned_fit };
|
||||||
if discr < fit {
|
if discr < fit {
|
||||||
return Err(LayoutError::UserError(
|
return Err(LayoutError::UserReprTooSmall);
|
||||||
"Integer::repr_discr: `#[repr]` hint too small for \
|
|
||||||
discriminant range of enum "
|
|
||||||
.into(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
return Ok((discr, ity.is_signed()));
|
return Ok((discr, ity.is_signed()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,16 +210,13 @@ fn recursive() {
|
||||||
struct BoxLike<T: ?Sized>(*mut T);
|
struct BoxLike<T: ?Sized>(*mut T);
|
||||||
struct Goal(BoxLike<Goal>);
|
struct Goal(BoxLike<Goal>);
|
||||||
}
|
}
|
||||||
check_fail(
|
check_fail(r#"struct Goal(Goal);"#, LayoutError::RecursiveTypeWithoutIndirection);
|
||||||
r#"struct Goal(Goal);"#,
|
|
||||||
LayoutError::UserError("infinite sized recursive type".into()),
|
|
||||||
);
|
|
||||||
check_fail(
|
check_fail(
|
||||||
r#"
|
r#"
|
||||||
struct Foo<T>(Foo<T>);
|
struct Foo<T>(Foo<T>);
|
||||||
struct Goal(Foo<i32>);
|
struct Goal(Foo<i32>);
|
||||||
"#,
|
"#,
|
||||||
LayoutError::UserError("infinite sized recursive type".into()),
|
LayoutError::RecursiveTypeWithoutIndirection,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4473,7 +4473,7 @@ impl B for u16 {
|
||||||
fn ttt() {
|
fn ttt() {
|
||||||
let inp = Y;
|
let inp = Y;
|
||||||
x::<u16>(&inp);
|
x::<u16>(&inp);
|
||||||
//^^^^ expected &X, got &Y
|
//^^^^ expected &X, got &Y
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue