Skip to content
This repository has been archived by the owner on Jan 29, 2025. It is now read-only.

Commit

Permalink
Improve error messages about address space
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Feb 2, 2022
1 parent 75692d3 commit 9b89c5f
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 37 deletions.
7 changes: 5 additions & 2 deletions src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,8 +529,11 @@ impl<T: Eq + hash::Hash> UniqueArena<T> {
}

/// Return this arena's value at `handle`, if that is a valid handle.
pub fn get_handle(&self, handle: Handle<T>) -> Option<&T> {
self.set.get_index(handle.index())
pub fn get_handle(&self, handle: Handle<T>) -> Result<&T, BadHandle> {
self.set.get_index(handle.index()).ok_or_else(|| BadHandle {
kind: std::any::type_name::<T>(),
index: handle.index(),
})
}
}

Expand Down
10 changes: 4 additions & 6 deletions src/valid/compose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ use crate::{
proc::TypeResolution,
};

use crate::Handle;
use crate::arena::{BadHandle, Handle};

#[derive(Clone, Debug, thiserror::Error)]
#[cfg_attr(test, derive(PartialEq))]
pub enum ComposeError {
#[error("Compose type {0:?} doesn't exist")]
TypeDoesntExist(Handle<crate::Type>),
#[error(transparent)]
BadHandle(#[from] BadHandle),
#[error("Composing of type {0:?} can't be done")]
Type(Handle<crate::Type>),
#[error("Composing expects {expected} components but {given} were given")]
Expand All @@ -28,9 +28,7 @@ pub fn validate_compose(
) -> Result<(), ComposeError> {
use crate::TypeInner as Ti;

let self_ty = type_arena
.get_handle(self_ty_handle)
.ok_or(ComposeError::TypeDoesntExist(self_ty_handle))?;
let self_ty = type_arena.get_handle(self_ty_handle)?;
match self_ty.inner {
// vectors are composed from scalars or other vectors
Ti::Vector { size, kind, width } => {
Expand Down
5 changes: 3 additions & 2 deletions src/valid/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1383,10 +1383,11 @@ impl super::Validator {
}
E::ArrayLength(expr) => match *resolver.resolve(expr)? {
Ti::Pointer { base, .. } => {
if let Some(&Ti::Array {
let base_ty = resolver.types.get_handle(base)?;
if let Ti::Array {
size: crate::ArraySize::Dynamic,
..
}) = resolver.types.get_handle(base).map(|ty| &ty.inner)
} = base_ty.inner
{
ShaderStages::all()
} else {
Expand Down
8 changes: 2 additions & 6 deletions src/valid/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -841,12 +841,8 @@ impl super::Validator {

#[cfg(feature = "validate")]
for (index, argument) in fun.arguments.iter().enumerate() {
let ty = module.types.get_handle(argument.ty).ok_or_else(|| {
FunctionError::InvalidArgumentType {
index,
name: argument.name.clone().unwrap_or_default(),
}
.with_span_handle(argument.ty, &module.types)
let ty = module.types.get_handle(argument.ty).map_err(|err| {
FunctionError::from(err).with_span_handle(argument.ty, &module.types)
})?;
match ty.inner.pointer_space() {
Some(crate::AddressSpace::Private)
Expand Down
46 changes: 31 additions & 15 deletions src/valid/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use super::{
analyzer::{FunctionInfo, GlobalUse},
Capabilities, Disalignment, FunctionError, ModuleInfo,
};
use crate::arena::{Handle, UniqueArena};
use crate::arena::{BadHandle, Handle, UniqueArena};

use crate::span::{AddSpan as _, MapErrWithSpan as _, SpanProvider as _, WithSpan};
use bit_set::BitSet;
Expand All @@ -12,10 +12,12 @@ const MAX_WORKGROUP_SIZE: u32 = 0x4000;

#[derive(Clone, Debug, thiserror::Error)]
pub enum GlobalVariableError {
#[error("Usage isn't compatible with the storage class")]
InvalidUsage,
#[error("Type isn't compatible with the storage class")]
InvalidType,
#[error(transparent)]
BadHandle(#[from] BadHandle),
#[error("Usage isn't compatible with address space {0:?}")]
InvalidUsage(crate::AddressSpace),
#[error("Type isn't compatible with with address space {0:?}")]
InvalidType(crate::AddressSpace),
#[error("Type flags {seen:?} do not meet the required {required:?}")]
MissingTypeFlags {
required: super::TypeFlags,
Expand All @@ -25,8 +27,12 @@ pub enum GlobalVariableError {
UnsupportedCapability(Capabilities),
#[error("Binding decoration is missing or not applicable")]
InvalidBinding,
#[error("Alignment requirements for this storage class are not met by {0:?}")]
Alignment(Handle<crate::Type>, #[source] Disalignment),
#[error("Alignment requirements for address space {0:?} are not met by {1:?}")]
Alignment(
crate::AddressSpace,
Handle<crate::Type>,
#[source] Disalignment,
),
}

#[derive(Clone, Debug, thiserror::Error)]
Expand Down Expand Up @@ -332,25 +338,35 @@ impl super::Validator {
use super::TypeFlags;

log::debug!("var {:?}", var);
let type_info = self
.types
.get(var.ty.index())
.ok_or(GlobalVariableError::InvalidType)?;
let type_info = self.types.get(var.ty.index()).ok_or_else(|| BadHandle {
kind: "type",
index: var.ty.index(),
})?;

let (required_type_flags, is_resource) = match var.space {
crate::AddressSpace::Function => return Err(GlobalVariableError::InvalidUsage),
crate::AddressSpace::Function => {
return Err(GlobalVariableError::InvalidUsage(var.space))
}
crate::AddressSpace::Storage { .. } => {
if let Err((ty_handle, disalignment)) = type_info.storage_layout {
if self.flags.contains(super::ValidationFlags::STRUCT_LAYOUTS) {
return Err(GlobalVariableError::Alignment(ty_handle, disalignment));
return Err(GlobalVariableError::Alignment(
var.space,
ty_handle,
disalignment,
));
}
}
(TypeFlags::DATA | TypeFlags::HOST_SHARED, true)
}
crate::AddressSpace::Uniform => {
if let Err((ty_handle, disalignment)) = type_info.uniform_layout {
if self.flags.contains(super::ValidationFlags::STRUCT_LAYOUTS) {
return Err(GlobalVariableError::Alignment(ty_handle, disalignment));
return Err(GlobalVariableError::Alignment(
var.space,
ty_handle,
disalignment,
));
}
}
(
Expand All @@ -362,7 +378,7 @@ impl super::Validator {
match types[var.ty].inner {
crate::TypeInner::Image { .. } | crate::TypeInner::Sampler { .. } => {}
_ => {
return Err(GlobalVariableError::InvalidType);
return Err(GlobalVariableError::InvalidType(var.space));
}
};
(TypeFlags::empty(), true)
Expand Down
10 changes: 4 additions & 6 deletions src/valid/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ mod r#type;
use crate::arena::{Arena, UniqueArena};

use crate::{
arena::Handle,
arena::{BadHandle, Handle},
proc::{LayoutError, Layouter},
FastHashSet,
};
Expand Down Expand Up @@ -114,6 +114,8 @@ pub struct Validator {

#[derive(Clone, Debug, thiserror::Error)]
pub enum ConstantError {
#[error(transparent)]
BadHandle(#[from] BadHandle),
#[error("The type doesn't match the constant")]
InvalidType,
#[error("The component handle {0:?} can not be resolved")]
Expand Down Expand Up @@ -240,11 +242,7 @@ impl Validator {
}
}
crate::ConstantInner::Composite { ty, ref components } => {
match types
.get_handle(ty)
.ok_or(ConstantError::InvalidType)?
.inner
{
match types.get_handle(ty)?.inner {
crate::TypeInner::Array {
size: crate::ArraySize::Constant(size_handle),
..
Expand Down

0 comments on commit 9b89c5f

Please sign in to comment.