diff --git a/naga/src/front/wgsl/error.rs b/naga/src/front/wgsl/error.rs index 6bbf9f476c..ac6bc617ea 100644 --- a/naga/src/front/wgsl/error.rs +++ b/naga/src/front/wgsl/error.rs @@ -174,8 +174,8 @@ pub(crate) enum Error<'a> { BadTexture(Span), BadTypeCast { span: Span, - from_type: Box, - to_type: Box, + from_type: String, + to_type: String, }, BadTextureSampleType { span: Span, @@ -211,8 +211,8 @@ pub(crate) enum Error<'a> { TypeNotInferable(Span), InitializationTypeMismatch { name: Span, - expected: Box, - got: Box, + expected: String, + got: String, }, DeclMissingTypeAndInit(Span), MissingAttribute(&'static str, Span), @@ -342,24 +342,24 @@ impl From<&'static str> for DiagnosticAttributeNotSupportedPosition { #[derive(Clone, Debug)] pub(crate) struct AutoConversionError { pub dest_span: Span, - pub dest_type: Box, + pub dest_type: String, pub source_span: Span, - pub source_type: Box, + pub source_type: String, } #[derive(Clone, Debug)] pub(crate) struct AutoConversionLeafScalarError { pub dest_span: Span, - pub dest_scalar: Box, + pub dest_scalar: String, pub source_span: Span, - pub source_type: Box, + pub source_type: String, } #[derive(Clone, Debug)] pub(crate) struct ConcretizationFailedError { pub expr_span: Span, - pub expr_type: Box, - pub scalar: Box, + pub expr_type: String, + pub scalar: String, pub inner: ConstantEvaluatorError, } @@ -1179,8 +1179,3 @@ impl<'a> Error<'a> { } } } - -#[test] -fn test_error_size() { - assert!(size_of::>() <= 48); -} diff --git a/naga/src/front/wgsl/index.rs b/naga/src/front/wgsl/index.rs index 7dafb6ef64..923cc75476 100644 --- a/naga/src/front/wgsl/index.rs +++ b/naga/src/front/wgsl/index.rs @@ -1,6 +1,6 @@ -use alloc::{vec, vec::Vec}; +use alloc::{boxed::Box, vec, vec::Vec}; -use super::Error; +use super::{Error, Result}; use crate::front::wgsl::parse::ast; use crate::{FastHashMap, Handle, Span}; @@ -17,7 +17,7 @@ impl<'a> Index<'a> { /// /// Return an error if the graph of references between declarations contains /// any cycles. - pub fn generate(tu: &ast::TranslationUnit<'a>) -> Result> { + pub fn generate(tu: &ast::TranslationUnit<'a>) -> Result<'a, Self> { // Produce a map from global definitions' names to their `Handle`s. // While doing so, reject conflicting definitions. let mut globals = FastHashMap::with_capacity_and_hasher(tu.decls.len(), Default::default()); @@ -25,12 +25,12 @@ impl<'a> Index<'a> { if let Some(ident) = decl_ident(decl) { let name = ident.name; if let Some(old) = globals.insert(name, handle) { - return Err(Error::Redefinition { + return Err(Box::new(Error::Redefinition { previous: decl_ident(&tu.decls[old]) .expect("decl should have ident for redefinition") .span, current: ident.span, - }); + })); } } } @@ -103,7 +103,7 @@ struct DependencySolver<'source, 'temp> { impl<'a> DependencySolver<'a, '_> { /// Produce the sorted list of declaration handles, and check for cycles. - fn solve(mut self) -> Result>>, Error<'a>> { + fn solve(mut self) -> Result<'a, Vec>>> { for (id, _) in self.module.decls.iter() { if self.visited[id.index()] { continue; @@ -117,7 +117,7 @@ impl<'a> DependencySolver<'a, '_> { /// Ensure that all declarations used by `id` have been added to the /// ordering, and then append `id` itself. - fn dfs(&mut self, id: Handle>) -> Result<(), Error<'a>> { + fn dfs(&mut self, id: Handle>) -> Result<'a, ()> { let decl = &self.module.decls[id]; let id_usize = id.index(); @@ -134,10 +134,10 @@ impl<'a> DependencySolver<'a, '_> { // Found a cycle. return if dep_id == id { // A declaration refers to itself directly. - Err(Error::RecursiveDeclaration { + Err(Box::new(Error::RecursiveDeclaration { ident: decl_ident(decl).expect("decl should have ident").span, usage: dep.usage, - }) + })) } else { // A declaration refers to itself indirectly, through // one or more other definitions. Report the entire path @@ -150,7 +150,7 @@ impl<'a> DependencySolver<'a, '_> { .find_map(|(i, dep)| (dep.decl == dep_id).then_some(i)) .unwrap_or(0); - Err(Error::CyclicDeclaration { + Err(Box::new(Error::CyclicDeclaration { ident: decl_ident(&self.module.decls[dep_id]) .expect("decl should have ident") .span, @@ -166,7 +166,7 @@ impl<'a> DependencySolver<'a, '_> { ) }) .collect(), - }) + })) }; } else if !self.visited[dep_id_usize] { self.dfs(dep_id)?; diff --git a/naga/src/front/wgsl/lower/construction.rs b/naga/src/front/wgsl/lower/construction.rs index b5fc3b66f0..0acb90f321 100644 --- a/naga/src/front/wgsl/lower/construction.rs +++ b/naga/src/front/wgsl/lower/construction.rs @@ -1,4 +1,5 @@ use alloc::{ + boxed::Box, format, string::{String, ToString}, vec, @@ -6,9 +7,9 @@ use alloc::{ }; use core::num::NonZeroU32; -use crate::front::wgsl::error::Error; use crate::front::wgsl::lower::{ExpressionContext, Lowerer}; use crate::front::wgsl::parse::ast; +use crate::front::wgsl::{Error, Result}; use crate::{Handle, Span}; /// A cooked form of `ast::ConstructorType` that uses Naga types whenever @@ -119,7 +120,7 @@ impl<'source> Lowerer<'source, '_> { ty_span: Span, components: &[Handle>], ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { use crate::proc::TypeResolution as Tr; let constructor_h = self.constructor(constructor, ctx)?; @@ -141,7 +142,7 @@ impl<'source> Lowerer<'source, '_> { let components = ast_components .iter() .map(|&expr| self.expression_for_abstract(expr, ctx)) - .collect::>()?; + .collect::>()?; let spans = ast_components .iter() .map(|&expr| ctx.ast_expressions.get_span(expr)) @@ -172,7 +173,7 @@ impl<'source> Lowerer<'source, '_> { | Constructor::PartialArray => { // We have no arguments from which to infer the result type, so // partial constructors aren't acceptable here. - return Err(Error::TypeNotInferable(ty_span)); + return Err(Box::new(Error::TypeNotInferable(ty_span))); } }, @@ -373,7 +374,7 @@ impl<'source> Lowerer<'source, '_> { Default::default(), ) }) - .collect::, _>>()?; + .collect::>>()?; let ty = ctx.ensure_type_exists(crate::TypeInner::Matrix { columns, @@ -410,7 +411,7 @@ impl<'source> Lowerer<'source, '_> { Default::default(), ) }) - .collect::, _>>()?; + .collect::>>()?; let ty = ctx.ensure_type_exists(crate::TypeInner::Matrix { columns, @@ -535,12 +536,12 @@ impl<'source> Lowerer<'source, '_> { // Bad conversion (type cast) (Components::One { span, ty_inner, .. }, constructor) => { - let from_type = ty_inner.to_wgsl(&ctx.module.to_ctx()).into(); - return Err(Error::BadTypeCast { + let from_type = ty_inner.to_wgsl(&ctx.module.to_ctx()); + return Err(Box::new(Error::BadTypeCast { span, from_type, - to_type: constructor.to_error_string(ctx).into(), - }); + to_type: constructor.to_error_string(ctx), + })); } // Too many parameters for scalar constructor @@ -549,11 +550,11 @@ impl<'source> Lowerer<'source, '_> { Constructor::Type((_, &crate::TypeInner::Scalar { .. })), ) => { let span = spans[1].until(spans.last().unwrap()); - return Err(Error::UnexpectedComponents(span)); + return Err(Box::new(Error::UnexpectedComponents(span))); } // Other types can't be constructed - _ => return Err(Error::TypeNotConstructible(ty_span)), + _ => return Err(Box::new(Error::TypeNotConstructible(ty_span))), } let expr = ctx.append_expression(expr, span)?; @@ -576,7 +577,7 @@ impl<'source> Lowerer<'source, '_> { &mut self, constructor: &ast::ConstructorType<'source>, ctx: &mut ExpressionContext<'source, '_, 'out>, - ) -> Result>, Error<'source>> { + ) -> Result<'source, Constructor>> { let handle = match *constructor { ast::ConstructorType::Scalar(scalar) => { let ty = ctx.ensure_type_exists(scalar.to_inner_scalar()); @@ -587,7 +588,7 @@ impl<'source> Lowerer<'source, '_> { let ty = self.resolve_ast_type(ty, &mut ctx.as_const())?; let scalar = match ctx.module.types[ty].inner { crate::TypeInner::Scalar(sc) => sc, - _ => return Err(Error::UnknownScalarType(ty_span)), + _ => return Err(Box::new(Error::UnknownScalarType(ty_span))), }; let ty = ctx.ensure_type_exists(crate::TypeInner::Vector { size, scalar }); Constructor::Type(ty) @@ -604,7 +605,7 @@ impl<'source> Lowerer<'source, '_> { let ty = self.resolve_ast_type(ty, &mut ctx.as_const())?; let scalar = match ctx.module.types[ty].inner { crate::TypeInner::Scalar(sc) => sc, - _ => return Err(Error::UnknownScalarType(ty_span)), + _ => return Err(Box::new(Error::UnknownScalarType(ty_span))), }; let ty = match scalar.kind { crate::ScalarKind::Float => ctx.ensure_type_exists(crate::TypeInner::Matrix { @@ -612,7 +613,7 @@ impl<'source> Lowerer<'source, '_> { rows, scalar, }), - _ => return Err(Error::BadMatrixScalarKind(ty_span, scalar)), + _ => return Err(Box::new(Error::BadMatrixScalarKind(ty_span, scalar))), }; Constructor::Type(ty) } diff --git a/naga/src/front/wgsl/lower/conversion.rs b/naga/src/front/wgsl/lower/conversion.rs index 58a7f39124..a72141522d 100644 --- a/naga/src/front/wgsl/lower/conversion.rs +++ b/naga/src/front/wgsl/lower/conversion.rs @@ -5,6 +5,7 @@ use alloc::{boxed::Box, string::String, vec::Vec}; use crate::front::wgsl::error::{ AutoConversionError, AutoConversionLeafScalarError, ConcretizationFailedError, }; +use crate::front::wgsl::Result; use crate::{Handle, Span}; impl<'source> super::ExpressionContext<'source, '_, '_> { @@ -25,7 +26,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> { expr: Handle, goal_ty: &crate::proc::TypeResolution, goal_span: Span, - ) -> Result, super::Error<'source>> { + ) -> Result<'source, Handle> { let expr_span = self.get_expression_span(expr); // Keep the TypeResolution so we can get type names for // structs in error messages. @@ -53,17 +54,17 @@ impl<'source> super::ExpressionContext<'source, '_, '_> { Some(scalars) => scalars, None => { let gctx = &self.module.to_ctx(); - let source_type = expr_resolution.to_wgsl(gctx).into(); - let dest_type = goal_ty.to_wgsl(gctx).into(); + let source_type = expr_resolution.to_wgsl(gctx); + let dest_type = goal_ty.to_wgsl(gctx); - return Err(super::Error::AutoConversion(Box::new( + return Err(Box::new(super::Error::AutoConversion(Box::new( AutoConversionError { dest_span: goal_span, dest_type, source_span: expr_span, source_type, }, - ))); + )))); } }; @@ -87,7 +88,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> { expr: Handle, goal_scalar: crate::Scalar, goal_span: Span, - ) -> Result, super::Error<'source>> { + ) -> Result<'source, Handle> { let expr_span = self.get_expression_span(expr); let expr_resolution = super::resolve!(self, expr); let types = &self.module.types; @@ -95,10 +96,10 @@ impl<'source> super::ExpressionContext<'source, '_, '_> { let make_error = || { let gctx = &self.module.to_ctx(); - let source_type = expr_resolution.to_wgsl(gctx).into(); + let source_type = expr_resolution.to_wgsl(gctx); super::Error::AutoConversionLeafScalar(Box::new(AutoConversionLeafScalarError { dest_span: goal_span, - dest_scalar: goal_scalar.to_wgsl().into(), + dest_scalar: goal_scalar.to_wgsl(), source_span: expr_span, source_type, })) @@ -106,7 +107,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> { let expr_scalar = match expr_inner.automatically_convertible_scalar(&self.module.types) { Some(scalar) => scalar, - None => return Err(make_error()), + None => return Err(Box::new(make_error())), }; if expr_scalar == goal_scalar { @@ -114,7 +115,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> { } if !expr_scalar.automatically_converts_to(goal_scalar) { - return Err(make_error()); + return Err(Box::new(make_error())); } assert!(expr_scalar.is_abstract()); @@ -127,12 +128,14 @@ impl<'source> super::ExpressionContext<'source, '_, '_> { expr: Handle, expr_span: Span, goal_scalar: crate::Scalar, - ) -> Result, super::Error<'source>> { + ) -> Result<'source, Handle> { let expr_inner = super::resolve_inner!(self, expr); if let crate::TypeInner::Array { .. } = *expr_inner { self.as_const_evaluator() .cast_array(expr, goal_scalar, expr_span) - .map_err(|err| super::Error::ConstantEvaluatorError(err.into(), expr_span)) + .map_err(|err| { + Box::new(super::Error::ConstantEvaluatorError(err.into(), expr_span)) + }) } else { let cast = crate::Expression::As { expr, @@ -149,7 +152,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> { exprs: &mut [Handle], goal_ty: &crate::proc::TypeResolution, goal_span: Span, - ) -> Result<(), super::Error<'source>> { + ) -> Result<'source, ()> { for expr in exprs.iter_mut() { *expr = self.try_automatic_conversions(*expr, goal_ty, goal_span)?; } @@ -170,7 +173,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> { exprs: &mut [Handle], goal_scalar: crate::Scalar, goal_span: Span, - ) -> Result<(), super::Error<'source>> { + ) -> Result<'source, ()> { use crate::proc::TypeResolution as Tr; use crate::TypeInner as Ti; let goal_scalar_res = Tr::Value(Ti::Scalar(goal_scalar)); @@ -195,9 +198,9 @@ impl<'source> super::ExpressionContext<'source, '_, '_> { } _ => { let span = self.get_expression_span(*expr); - return Err(super::Error::InvalidConstructorComponentType( + return Err(Box::new(super::Error::InvalidConstructorComponentType( span, i as i32, - )); + ))); } } } @@ -210,7 +213,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> { &mut self, expr: &mut Handle, goal: crate::Scalar, - ) -> Result<(), super::Error<'source>> { + ) -> Result<'source, ()> { let inner = super::resolve_inner!(self, *expr); // Do nothing if `inner` doesn't even have leaf scalars; // it's a type error that validation will catch. @@ -241,7 +244,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> { &mut self, exprs: &mut [Handle], goal: crate::Scalar, - ) -> Result<(), super::Error<'source>> { + ) -> Result<'source, ()> { for expr in exprs.iter_mut() { self.convert_to_leaf_scalar(expr, goal)?; } @@ -255,7 +258,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> { pub fn concretize( &mut self, mut expr: Handle, - ) -> Result, super::Error<'source>> { + ) -> Result<'source, Handle> { let inner = super::resolve_inner!(self, expr); if let Some(scalar) = inner.automatically_convertible_scalar(&self.module.types) { let concretized = scalar.concretize(); @@ -272,8 +275,8 @@ impl<'source> super::ExpressionContext<'source, '_, '_> { let expr_type = &self.typifier()[expr]; super::Error::ConcretizationFailed(Box::new(ConcretizationFailedError { expr_span, - expr_type: expr_type.to_wgsl(&self.module.to_ctx()).into(), - scalar: concretized.to_wgsl().into(), + expr_type: expr_type.to_wgsl(&self.module.to_ctx()), + scalar: concretized.to_wgsl(), inner: err, })) })?; @@ -303,7 +306,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> { pub fn automatic_conversion_consensus<'handle, I>( &self, components: I, - ) -> Result + ) -> core::result::Result where I: IntoIterator>, I::IntoIter: Clone, // for debugging diff --git a/naga/src/front/wgsl/lower/mod.rs b/naga/src/front/wgsl/lower/mod.rs index ba9421f848..00246e3156 100644 --- a/naga/src/front/wgsl/lower/mod.rs +++ b/naga/src/front/wgsl/lower/mod.rs @@ -1,5 +1,6 @@ use alloc::{ borrow::ToOwned, + boxed::Box, string::{String, ToString}, vec::Vec, }; @@ -9,6 +10,7 @@ use crate::front::wgsl::error::{Error, ExpectedToken, InvalidAssignmentType}; use crate::front::wgsl::index::Index; use crate::front::wgsl::parse::number::Number; use crate::front::wgsl::parse::{ast, conv}; +use crate::front::wgsl::Result; use crate::front::Typifier; use crate::proc::{ ensure_block_returns, Alignment, ConstantEvaluator, Emitter, Layouter, ResolveContext, @@ -468,16 +470,16 @@ impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> { &mut self, expr: crate::Expression, span: Span, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { let mut eval = self.as_const_evaluator(); eval.try_eval_and_append(expr, span) - .map_err(|e| Error::ConstantEvaluatorError(e.into(), span)) + .map_err(|e| Box::new(Error::ConstantEvaluatorError(e.into(), span))) } fn const_eval_expr_to_u32( &self, handle: Handle, - ) -> Result { + ) -> core::result::Result { match self.expr_type { ExpressionContextType::Runtime(ref ctx) => { if !ctx.local_expression_kind_tracker.is_const(handle) { @@ -525,24 +527,24 @@ impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> { &mut self, local: &Handle, span: Span, - ) -> Result>, Error<'source>> { + ) -> Result<'source, Typed>> { match self.expr_type { ExpressionContextType::Runtime(ref ctx) => Ok(ctx.local_table[local].runtime()), ExpressionContextType::Constant(Some(ref ctx)) => ctx.local_table[local] .const_time() - .ok_or(Error::UnexpectedOperationInConstContext(span)), - _ => Err(Error::UnexpectedOperationInConstContext(span)), + .ok_or(Box::new(Error::UnexpectedOperationInConstContext(span))), + _ => Err(Box::new(Error::UnexpectedOperationInConstContext(span))), } } fn runtime_expression_ctx( &mut self, span: Span, - ) -> Result<&mut LocalExpressionContext<'temp, 'out>, Error<'source>> { + ) -> Result<'source, &mut LocalExpressionContext<'temp, 'out>> { match self.expr_type { ExpressionContextType::Runtime(ref mut ctx) => Ok(ctx), ExpressionContextType::Constant(_) | ExpressionContextType::Override => { - Err(Error::UnexpectedOperationInConstContext(span)) + Err(Box::new(Error::UnexpectedOperationInConstContext(span))) } } } @@ -552,13 +554,13 @@ impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> { expr: Handle, component_span: Span, gather_span: Span, - ) -> Result> { + ) -> Result<'source, crate::SwizzleComponent> { match self.expr_type { ExpressionContextType::Runtime(ref rctx) => { if !rctx.local_expression_kind_tracker.is_const(expr) { - return Err(Error::ExpectedConstExprConcreteIntegerScalar( + return Err(Box::new(Error::ExpectedConstExprConcreteIntegerScalar( component_span, - )); + ))); } let index = self @@ -576,13 +578,13 @@ impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> { crate::SwizzleComponent::XYZW .get(index as usize) .copied() - .ok_or(Error::InvalidGatherComponent(component_span)) + .ok_or(Box::new(Error::InvalidGatherComponent(component_span))) } // This means a `gather` operation appeared in a constant expression. // This error refers to the `gather` itself, not its "component" argument. - ExpressionContextType::Constant(_) | ExpressionContextType::Override => { - Err(Error::UnexpectedOperationInConstContext(gather_span)) - } + ExpressionContextType::Constant(_) | ExpressionContextType::Override => Err(Box::new( + Error::UnexpectedOperationInConstContext(gather_span), + )), } } @@ -599,7 +601,7 @@ impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> { fn register_type( &mut self, handle: Handle, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { self.grow_types(handle)?; // This is equivalent to calling ExpressionContext::typifier(), // except that this lets the borrow checker see that it's okay @@ -634,10 +636,7 @@ impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> { /// [`TypeResolution`]: crate::proc::TypeResolution /// [`register_type`]: Self::register_type /// [`Typifier`]: Typifier - fn grow_types( - &mut self, - handle: Handle, - ) -> Result<&mut Self, Error<'source>> { + fn grow_types(&mut self, handle: Handle) -> Result<'source, &mut Self> { let empty_arena = Arena::new(); let resolve_ctx; let typifier; @@ -670,10 +669,10 @@ impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> { &mut self, image: Handle, span: Span, - ) -> Result<(crate::ImageClass, bool), Error<'source>> { + ) -> Result<'source, (crate::ImageClass, bool)> { match *resolve_inner!(self, image) { crate::TypeInner::Image { class, arrayed, .. } => Ok((class, arrayed)), - _ => Err(Error::BadTexture(span)), + _ => Err(Box::new(Error::BadTexture(span))), } } @@ -704,7 +703,7 @@ impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> { op: crate::BinaryOperator, left: &mut Handle, right: &mut Handle, - ) -> Result<(), Error<'source>> { + ) -> Result<'source, ()> { if matches!( op, crate::BinaryOperator::Add @@ -743,7 +742,7 @@ impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> { &mut self, expression: crate::Expression, span: Span, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { match self.expr_type { ExpressionContextType::Runtime(ref mut rctx) | ExpressionContextType::Constant(Some(ref mut rctx)) => { @@ -770,7 +769,7 @@ impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> { fn apply_load_rule( &mut self, expr: Typed>, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { match expr { Typed::Reference(pointer) => { let load = crate::Expression::Load { pointer }; @@ -795,29 +794,29 @@ struct ArgumentContext<'ctx, 'source> { } impl<'source> ArgumentContext<'_, 'source> { - pub fn finish(self) -> Result<(), Error<'source>> { + pub fn finish(self) -> Result<'source, ()> { if self.args.len() == 0 { Ok(()) } else { - Err(Error::WrongArgumentCount { + Err(Box::new(Error::WrongArgumentCount { found: self.total_args, expected: self.min_args..self.args_used + 1, span: self.span, - }) + })) } } - pub fn next(&mut self) -> Result>, Error<'source>> { + pub fn next(&mut self) -> Result<'source, Handle>> { match self.args.next().copied() { Some(arg) => { self.args_used += 1; Ok(arg) } - None => Err(Error::WrongArgumentCount { + None => Err(Box::new(Error::WrongArgumentCount { found: self.total_args, expected: self.min_args..self.args_used + 1, span: self.span, - }), + })), } } } @@ -884,7 +883,10 @@ impl Typed { } } - fn try_map(self, mut f: impl FnMut(T) -> Result) -> Result, E> { + fn try_map( + self, + mut f: impl FnMut(T) -> core::result::Result, + ) -> core::result::Result, E> { Ok(match self { Self::Reference(expr) => Typed::Reference(f(expr)?), Self::Plain(expr) => Typed::Plain(f(expr)?), @@ -917,24 +919,24 @@ impl Components { } } - fn single_component(name: &str, name_span: Span) -> Result { + fn single_component(name: &str, name_span: Span) -> Result { let ch = name.chars().next().ok_or(Error::BadAccessor(name_span))?; match Self::letter_component(ch) { Some(sc) => Ok(sc as u32), - None => Err(Error::BadAccessor(name_span)), + None => Err(Box::new(Error::BadAccessor(name_span))), } } /// Construct a `Components` value from a 'member' name, like `"wzy"` or `"x"`. /// /// Use `name_span` for reporting errors in parsing the component string. - fn new(name: &str, name_span: Span) -> Result { + fn new(name: &str, name_span: Span) -> Result { let size = match name.len() { 1 => return Ok(Components::Single(Self::single_component(name, name_span)?)), 2 => crate::VectorSize::Bi, 3 => crate::VectorSize::Tri, 4 => crate::VectorSize::Quad, - _ => return Err(Error::BadAccessor(name_span)), + _ => return Err(Box::new(Error::BadAccessor(name_span))), }; let mut pattern = [crate::SwizzleComponent::X; 4]; @@ -947,7 +949,7 @@ impl Components { { Ok(Components::Swizzle { size, pattern }) } else { - Err(Error::BadAccessor(name_span)) + Err(Box::new(Error::BadAccessor(name_span))) } } } @@ -1052,10 +1054,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { Self { index } } - pub fn lower( - &mut self, - tu: ast::TranslationUnit<'source>, - ) -> Result> { + pub fn lower(&mut self, tu: ast::TranslationUnit<'source>) -> Result<'source, crate::Module> { let mut module = crate::Module { diagnostic_filters: tu.diagnostic_filters, diagnostic_filter_leaf: tu.diagnostic_filter_leaf, @@ -1233,7 +1232,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { explicit_ty: Option>, abstract_rule: AbstractRule, ectx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result<(Handle, Option>), Error<'source>> { + ) -> Result<'source, (Handle, Option>)> { let ty; let initializer; match (init, explicit_ty) { @@ -1242,24 +1241,24 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { let ty_res = crate::proc::TypeResolution::Handle(explicit_ty); let init = ectx .try_automatic_conversions(init, &ty_res, name.span) - .map_err(|error| match error { - Error::AutoConversion(e) => Error::InitializationTypeMismatch { + .map_err(|error| match *error { + Error::AutoConversion(e) => Box::new(Error::InitializationTypeMismatch { name: name.span, expected: e.dest_type, got: e.source_type, - }, - other => other, + }), + _ => error, })?; let init_ty = ectx.register_type(init)?; let explicit_inner = &ectx.module.types[explicit_ty].inner; let init_inner = &ectx.module.types[init_ty].inner; if !explicit_inner.equivalent(init_inner, &ectx.module.types) { - return Err(Error::InitializationTypeMismatch { + return Err(Box::new(Error::InitializationTypeMismatch { name: name.span, - expected: explicit_inner.to_wgsl(&ectx.module.to_ctx()).into(), - got: init_inner.to_wgsl(&ectx.module.to_ctx()).into(), - }); + expected: explicit_inner.to_wgsl(&ectx.module.to_ctx()), + got: init_inner.to_wgsl(&ectx.module.to_ctx()), + })); } ty = explicit_ty; initializer = Some(init); @@ -1276,7 +1275,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { ty = explicit_ty; initializer = None; } - (None, None) => return Err(Error::DeclMissingTypeAndInit(name.span)), + (None, None) => return Err(Box::new(Error::DeclMissingTypeAndInit(name.span))), } Ok((ty, initializer)) } @@ -1286,7 +1285,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { f: &ast::Function<'source>, span: Span, ctx: &mut GlobalContext<'source, '_, '_>, - ) -> Result> { + ) -> Result<'source, LoweredGlobalDecl> { let mut local_table = FastHashMap::default(); let mut expressions = Arena::new(); let mut named_expressions = FastIndexMap::default(); @@ -1296,7 +1295,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { .arguments .iter() .enumerate() - .map(|(i, arg)| -> Result<_, Error<'_>> { + .map(|(i, arg)| -> Result<'_, _> { let ty = self.resolve_ast_type(arg.ty, &mut ctx.as_const())?; let expr = expressions .append(crate::Expression::FunctionArgument(i as u32), arg.name.span); @@ -1310,12 +1309,12 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { binding: self.binding(&arg.binding, ty, ctx)?, }) }) - .collect::, _>>()?; + .collect::>>()?; let result = f .result .as_ref() - .map(|res| -> Result<_, Error<'_>> { + .map(|res| -> Result<'_, _> { let ty = self.resolve_ast_type(res.ty, &mut ctx.as_const())?; Ok(crate::FunctionResult { ty, @@ -1370,8 +1369,8 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { Ok(value) => { workgroup_size_out[i] = value.0; } - err => { - if let Err(Error::ConstantEvaluatorError(ref ty, _)) = err { + Err(err) => { + if let Error::ConstantEvaluatorError(ref ty, _) = *err { match **ty { crate::proc::ConstantEvaluatorError::OverrideExpr => { workgroup_size_overrides_out[i] = @@ -1381,11 +1380,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { )?); } _ => { - err?; + return Err(err); } } } else { - err?; + return Err(err); } } } @@ -1423,12 +1422,14 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { &mut self, size_expr: Handle>, ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { let span = ctx.ast_expressions.get_span(size_expr); let expr = self.expression(size_expr, ctx)?; match resolve_inner!(ctx, expr).scalar_kind().ok_or(0) { Ok(crate::ScalarKind::Sint) | Ok(crate::ScalarKind::Uint) => Ok(expr), - _ => Err(Error::ExpectedConstExprConcreteIntegerScalar(span)), + _ => Err(Box::new(Error::ExpectedConstExprConcreteIntegerScalar( + span, + ))), } } @@ -1437,7 +1438,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { b: &ast::Block<'source>, is_inside_loop: bool, ctx: &mut StatementContext<'source, '_, '_>, - ) -> Result> { + ) -> Result<'source, crate::Block> { let mut block = crate::Block::default(); for stmt in b.stmts.iter() { @@ -1453,7 +1454,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { block: &mut crate::Block, is_inside_loop: bool, ctx: &mut StatementContext<'source, '_, '_>, - ) -> Result<(), Error<'source>> { + ) -> Result<'source, ()> { let out = match stmt.kind { ast::StatementKind::Block(ref block) => { let block = self.block(block, is_inside_loop, ctx)?; @@ -1487,11 +1488,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { .equivalent(&ctx.module.types[init_ty].inner, &ctx.module.types) { let gctx = &ctx.module.to_ctx(); - return Err(Error::InitializationTypeMismatch { + return Err(Box::new(Error::InitializationTypeMismatch { name: l.name.span, - expected: ty.to_wgsl(gctx).into(), - got: init_ty.to_wgsl(gctx).into(), - }); + expected: ty.to_wgsl(gctx), + got: init_ty.to_wgsl(gctx), + })); } } @@ -1650,12 +1651,12 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { | crate::Scalar::ABSTRACT_INT, ) => Ok((expr, span)), _ => match i { - 0 => Err(Error::InvalidSwitchSelector { span }), - _ => Err(Error::InvalidSwitchCase { span }), + 0 => Err(Box::new(Error::InvalidSwitchSelector { span })), + _ => Err(Box::new(Error::InvalidSwitchCase { span })), }, } }) - .collect::, Vec<_>), _>>()?; + .collect::, Vec<_>)>>()?; let mut consensus = ectx.automatic_conversion_consensus(&exprs) @@ -1699,7 +1700,9 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { crate::SwitchValue::U32(value) } _ => { - return Err(Error::InvalidSwitchCase { span }); + return Err(Box::new(Error::InvalidSwitchCase { + span, + })); } } } @@ -1709,7 +1712,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { fall_through: case.fall_through, }) }) - .collect::>()?; + .collect::>()?; crate::Statement::Switch { selector, cases } } @@ -1797,10 +1800,10 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { Typed::Reference(handle) => handle, Typed::Plain(handle) => { let ty = ctx.invalid_assignment_type(handle); - return Err(Error::InvalidAssignment { + return Err(Box::new(Error::InvalidAssignment { span: target_span, ty, - }); + })); } }; @@ -1863,7 +1866,9 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { .expression_for_reference(value, &mut ctx.as_expression(block, &mut emitter))?; let target_handle = match target { Typed::Reference(handle) => handle, - Typed::Plain(_) => return Err(Error::BadIncrDecrReferenceType(value_span)), + Typed::Plain(_) => { + return Err(Box::new(Error::BadIncrDecrReferenceType(value_span))) + } }; let mut ectx = ctx.as_expression(block, &mut emitter); @@ -1873,16 +1878,16 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { } => scalar, crate::TypeInner::Pointer { base, .. } => match ectx.module.types[base].inner { crate::TypeInner::Scalar(scalar) => scalar, - _ => return Err(Error::BadIncrDecrReferenceType(value_span)), + _ => return Err(Box::new(Error::BadIncrDecrReferenceType(value_span))), }, - _ => return Err(Error::BadIncrDecrReferenceType(value_span)), + _ => return Err(Box::new(Error::BadIncrDecrReferenceType(value_span))), }; let literal = match scalar.kind { crate::ScalarKind::Sint | crate::ScalarKind::Uint => { crate::Literal::one(scalar) .ok_or(Error::BadIncrDecrReferenceType(value_span))? } - _ => return Err(Error::BadIncrDecrReferenceType(value_span)), + _ => return Err(Box::new(Error::BadIncrDecrReferenceType(value_span))), }; let right = @@ -1959,7 +1964,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { &mut self, expr: Handle>, ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { let expr = self.expression_for_abstract(expr, ctx)?; ctx.concretize(expr) } @@ -1968,7 +1973,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { &mut self, expr: Handle>, ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { let expr = self.expression_for_reference(expr, ctx)?; ctx.apply_load_rule(expr) } @@ -1977,7 +1982,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { &mut self, expr: Handle>, ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result>, Error<'source>> { + ) -> Result<'source, Typed>> { let span = ctx.ast_expressions.get_span(expr); let expr = &ctx.ast_expressions[expr]; @@ -2024,7 +2029,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { LoweredGlobalDecl::Function { .. } | LoweredGlobalDecl::Type(_) | LoweredGlobalDecl::EntryPoint => { - return Err(Error::Unexpected(span, ExpectedToken::Variable)); + return Err(Box::new(Error::Unexpected(span, ExpectedToken::Variable))); } }; @@ -2051,7 +2056,10 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { return Ok(Typed::Plain(handle)); } Typed::Plain(_) => { - return Err(Error::NotReference("the operand of the `&` operator", span)); + return Err(Box::new(Error::NotReference( + "the operand of the `&` operator", + span, + ))); } } } @@ -2060,7 +2068,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { let pointer = self.expression(expr, ctx)?; if resolve_inner!(ctx, pointer).pointer_space().is_none() { - return Err(Error::NotPointer(span)); + return Err(Box::new(Error::NotPointer(span))); } // No code is generated. We just declare the pointer a reference now. @@ -2091,7 +2099,9 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { } lowered_base.try_map(|base| match ctx.const_eval_expr_to_u32(index).ok() { - Some(index) => Ok::<_, Error>(crate::Expression::AccessIndex { base, index }), + Some(index) => { + Ok::<_, Box>(crate::Expression::AccessIndex { base, index }) + } None => { // When an abstract array value e is indexed by an expression // that is not a const-expression, then the array is concretized @@ -2168,7 +2178,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { .map(|base| crate::Expression::AccessIndex { base, index }), } } - _ => return Err(Error::BadAccessor(field.span)), + _ => return Err(Box::new(Error::BadAccessor(field.span))), }; access @@ -2183,11 +2193,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { _ => { let ty = resolve!(ctx, expr); let gctx = &ctx.module.to_ctx(); - return Err(Error::BadTypeCast { - from_type: ty.to_wgsl(gctx).into(), + return Err(Box::new(Error::BadTypeCast { + from_type: ty.to_wgsl(gctx), span: ty_span, - to_type: to_resolved.to_wgsl(gctx).into(), - }); + to_type: to_resolved.to_wgsl(gctx), + })); } }; @@ -2209,7 +2219,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { right: Handle>, span: Span, ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result, Error<'source>> { + ) -> Result<'source, Typed> { // Load both operands. let mut left = self.expression_for_abstract(left, ctx)?; let mut right = self.expression_for_abstract(right, ctx)?; @@ -2297,7 +2307,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { arguments: &[Handle>], ctx: &mut ExpressionContext<'source, '_, '_>, is_statement: bool, - ) -> Result>, Error<'source>> { + ) -> Result<'source, Option>> { let function_span = function.span; match ctx.globals.get(function.name) { Some(&LoweredGlobalDecl::Type(ty)) => { @@ -2314,8 +2324,13 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { &LoweredGlobalDecl::Const(_) | &LoweredGlobalDecl::Override(_) | &LoweredGlobalDecl::Var(_), - ) => Err(Error::Unexpected(function_span, ExpectedToken::Function)), - Some(&LoweredGlobalDecl::EntryPoint) => Err(Error::CalledEntryPoint(function_span)), + ) => Err(Box::new(Error::Unexpected( + function_span, + ExpectedToken::Function, + ))), + Some(&LoweredGlobalDecl::EntryPoint) => { + Err(Box::new(Error::CalledEntryPoint(function_span))) + } Some(&LoweredGlobalDecl::Function { handle: function, must_use, @@ -2341,12 +2356,12 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { ctx.ast_expressions.get_span(arg), ) }) - .collect::, _>>()?; + .collect::>>()?; let has_result = ctx.module.functions[function].result.is_some(); if must_use && is_statement { - return Err(Error::FunctionMustUseUnused(function_span)); + return Err(Box::new(Error::FunctionMustUseUnused(function_span))); } let rctx = ctx.runtime_expression_ctx(span)?; @@ -2535,7 +2550,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { comparison: true, } } - _ => return Err(Error::InvalidAtomicOperandType(value_span)), + _ => { + return Err(Box::new(Error::InvalidAtomicOperandType( + value_span, + ))) + } }; let result = ctx.interrupt_emitter(expression, span)?; @@ -2643,7 +2662,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { ref other => { log::error!("Type {other:?} passed to workgroupUniformLoad"); let span = ctx.ast_expressions.get_span(expr); - return Err(Error::InvalidWorkGroupUniformLoad(span)); + return Err(Box::new(Error::InvalidWorkGroupUniformLoad(span))); } }; let result = ctx.interrupt_emitter( @@ -2920,7 +2939,9 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { .push(crate::Statement::SubgroupBallot { result, predicate }, span); return Ok(Some(result)); } - _ => return Err(Error::UnknownIdent(function.span, function.name)), + _ => { + return Err(Box::new(Error::UnknownIdent(function.span, function.name))) + } } }; @@ -2934,7 +2955,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { &mut self, expr: Handle>, ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { let span = ctx.ast_expressions.get_span(expr); let pointer = self.expression(expr, ctx)?; @@ -2943,12 +2964,12 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { crate::TypeInner::Atomic { .. } => Ok(pointer), ref other => { log::error!("Pointer type to {:?} passed to atomic op", other); - Err(Error::InvalidAtomicPointer(span)) + Err(Box::new(Error::InvalidAtomicPointer(span))) } }, ref other => { log::error!("Type {:?} passed to atomic op", other); - Err(Error::InvalidAtomicPointer(span)) + Err(Box::new(Error::InvalidAtomicPointer(span))) } } } @@ -2960,7 +2981,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { args: &[Handle>], is_statement: bool, ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result>, Error<'source>> { + ) -> Result<'source, Option>> { let mut args = ctx.prepare_args(args, 2, span); let pointer = self.atomic_pointer(args.next()?, ctx)?; @@ -3013,14 +3034,14 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { args: &[Handle>], span: Span, ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result> { + ) -> Result<'source, crate::Expression> { let mut args = ctx.prepare_args(args, fun.min_argument_count(), span); fn get_image_and_span<'source>( lowerer: &mut Lowerer<'source, '_>, args: &mut ArgumentContext<'_, 'source>, ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result<(Handle, Span), Error<'source>> { + ) -> Result<'source, (Handle, Span)> { let image = args.next()?; let image_span = ctx.ast_expressions.get_span(image); let image = lowerer.expression(image, ctx)?; @@ -3135,7 +3156,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { collective_op: crate::CollectiveOperation, arguments: &[Handle>], ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { let mut args = ctx.prepare_args(arguments, 1, span); let argument = self.expression(args.next()?, ctx)?; @@ -3164,7 +3185,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { mode: SubgroupGather, arguments: &[Handle>], ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { let mut args = ctx.prepare_args(arguments, 2, span); let argument = self.expression(args.next()?, ctx)?; @@ -3207,7 +3228,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { s: &ast::Struct<'source>, span: Span, ctx: &mut GlobalContext<'source, '_, '_>, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { let mut offset = 0; let mut struct_alignment = Alignment::ONE; let mut members = Vec::with_capacity(s.members.len()); @@ -3223,7 +3244,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { let member_size = if let Some(size_expr) = member.size { let (size, span) = self.const_u32(size_expr, &mut ctx.as_const())?; if size < member_min_size { - return Err(Error::SizeAttributeTooLow(span, member_min_size)); + return Err(Box::new(Error::SizeAttributeTooLow(span, member_min_size))); } else { size } @@ -3235,12 +3256,15 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { let (align, span) = self.const_u32(align_expr, &mut ctx.as_const())?; if let Some(alignment) = Alignment::new(align) { if alignment < member_min_alignment { - return Err(Error::AlignAttributeTooLow(span, member_min_alignment)); + return Err(Box::new(Error::AlignAttributeTooLow( + span, + member_min_alignment, + ))); } else { alignment } } else { - return Err(Error::NonPowerOfTwoAlignAttribute(span)); + return Err(Box::new(Error::NonPowerOfTwoAlignAttribute(span))); } } else { member_min_alignment @@ -3281,7 +3305,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { &mut self, expr: Handle>, ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result<(u32, Span), Error<'source>> { + ) -> Result<'source, (u32, Span)> { let span = ctx.ast_expressions.get_span(expr); let expr = self.expression(expr, ctx)?; let value = ctx @@ -3301,27 +3325,29 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { &mut self, size: ast::ArraySize<'source>, ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result> { + ) -> Result<'source, crate::ArraySize> { Ok(match size { ast::ArraySize::Constant(expr) => { let span = ctx.ast_expressions.get_span(expr); let const_expr = self.expression(expr, &mut ctx.as_const()); match const_expr { Ok(value) => { - let len = ctx.const_eval_expr_to_u32(value).map_err(|err| match err { - crate::proc::U32EvalError::NonConst => { - Error::ExpectedConstExprConcreteIntegerScalar(span) - } - crate::proc::U32EvalError::Negative => { - Error::ExpectedPositiveArrayLength(span) - } + let len = ctx.const_eval_expr_to_u32(value).map_err(|err| { + Box::new(match err { + crate::proc::U32EvalError::NonConst => { + Error::ExpectedConstExprConcreteIntegerScalar(span) + } + crate::proc::U32EvalError::Negative => { + Error::ExpectedPositiveArrayLength(span) + } + }) })?; let size = NonZeroU32::new(len).ok_or(Error::ExpectedPositiveArrayLength(span))?; crate::ArraySize::Constant(size) } - err => { - if let Err(Error::ConstantEvaluatorError(ref ty, _)) = err { + Err(err) => { + if let Error::ConstantEvaluatorError(ref ty, _) = *err { match **ty { crate::proc::ConstantEvaluatorError::OverrideExpr => { crate::ArraySize::Pending(self.array_size_override( @@ -3331,13 +3357,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { )?) } _ => { - err?; - unreachable!() + return Err(err); } } } else { - err?; - unreachable!() + return Err(err); } } } @@ -3351,7 +3375,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { size_expr: Handle>, ctx: &mut ExpressionContext<'source, '_, '_>, span: Span, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { let expr = self.expression(size_expr, ctx)?; match resolve_inner!(ctx, expr).scalar_kind().ok_or(0) { Ok(crate::ScalarKind::Sint) | Ok(crate::ScalarKind::Uint) => Ok({ @@ -3370,7 +3394,9 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { ) } }), - _ => Err(Error::ExpectedConstExprConcreteIntegerScalar(span)), + _ => Err(Box::new(Error::ExpectedConstExprConcreteIntegerScalar( + span, + ))), } } @@ -3388,14 +3414,14 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { handle: Handle>, name: Option, ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { let inner = match ctx.types[handle] { ast::Type::Scalar(scalar) => scalar.to_inner_scalar(), ast::Type::Vector { size, ty, ty_span } => { let ty = self.resolve_ast_type(ty, ctx)?; let scalar = match ctx.module.types[ty].inner { crate::TypeInner::Scalar(sc) => sc, - _ => return Err(Error::UnknownScalarType(ty_span)), + _ => return Err(Box::new(Error::UnknownScalarType(ty_span))), }; crate::TypeInner::Vector { size, scalar } } @@ -3408,7 +3434,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { let ty = self.resolve_ast_type(ty, ctx)?; let scalar = match ctx.module.types[ty].inner { crate::TypeInner::Scalar(sc) => sc, - _ => return Err(Error::UnknownScalarType(ty_span)), + _ => return Err(Box::new(Error::UnknownScalarType(ty_span))), }; match scalar.kind { crate::ScalarKind::Float => crate::TypeInner::Matrix { @@ -3416,7 +3442,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { rows, scalar, }, - _ => return Err(Error::BadMatrixScalarKind(ty_span, scalar)), + _ => return Err(Box::new(Error::BadMatrixScalarKind(ty_span, scalar))), } } ast::Type::Atomic(scalar) => scalar.to_inner_atomic(), @@ -3461,8 +3487,8 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { ast::Type::User(ref ident) => { return match ctx.globals.get(ident.name) { Some(&LoweredGlobalDecl::Type(handle)) => Ok(handle), - Some(_) => Err(Error::Unexpected(ident.span, ExpectedToken::Type)), - None => Err(Error::UnknownType(ident.span)), + Some(_) => Err(Box::new(Error::Unexpected(ident.span, ExpectedToken::Type))), + None => Err(Box::new(Error::UnknownType(ident.span))), } } }; @@ -3475,7 +3501,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { &mut self, handle: Handle>, ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { self.resolve_named_ast_type(handle, None, ctx) } @@ -3484,7 +3510,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { binding: &Option>, ty: Handle, ctx: &mut GlobalContext<'source, '_, '_>, - ) -> Result, Error<'source>> { + ) -> Result<'source, Option> { Ok(match *binding { Some(ast::Binding::BuiltIn(b)) => Some(crate::Binding::BuiltIn(b)), Some(ast::Binding::Location { @@ -3516,7 +3542,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { &mut self, expr: Handle>, ctx: &mut ExpressionContext<'source, '_, '_>, - ) -> Result, Error<'source>> { + ) -> Result<'source, Handle> { let span = ctx.ast_expressions.get_span(expr); let pointer = self.expression(expr, ctx)?; @@ -3525,12 +3551,12 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { crate::TypeInner::RayQuery { .. } => Ok(pointer), ref other => { log::error!("Pointer type to {:?} passed to ray query op", other); - Err(Error::InvalidRayQueryPointer(span)) + Err(Box::new(Error::InvalidRayQueryPointer(span))) } }, ref other => { log::error!("Type {:?} passed to ray query op", other); - Err(Error::InvalidRayQueryPointer(span)) + Err(Box::new(Error::InvalidRayQueryPointer(span))) } } } diff --git a/naga/src/front/wgsl/mod.rs b/naga/src/front/wgsl/mod.rs index dc97298acd..7ea66265cb 100644 --- a/naga/src/front/wgsl/mod.rs +++ b/naga/src/front/wgsl/mod.rs @@ -17,6 +17,7 @@ pub use crate::front::wgsl::parse::directive::language_extension::{ ImplementedLanguageExtension, LanguageExtension, UnimplementedLanguageExtension, }; +use alloc::boxed::Box; use thiserror::Error; use crate::front::wgsl::error::Error; @@ -27,6 +28,8 @@ use crate::Scalar; #[cfg(test)] use std::println; +pub(crate) type Result<'a, T> = core::result::Result>>; + pub struct Frontend { parser: Parser, } @@ -38,11 +41,11 @@ impl Frontend { } } - pub fn parse(&mut self, source: &str) -> Result { + pub fn parse(&mut self, source: &str) -> core::result::Result { self.inner(source).map_err(|x| x.as_parse_error(source)) } - fn inner<'a>(&mut self, source: &'a str) -> Result> { + fn inner<'a>(&mut self, source: &'a str) -> Result<'a, crate::Module> { let tu = self.parser.parse(source)?; let index = index::Index::generate(&tu)?; let module = Lowerer::new(&index).lower(tu)?; @@ -62,7 +65,7 @@ impl Frontend { /// for this, particularly if calls to this method are exposed to user input. /// /// -pub fn parse_str(source: &str) -> Result { +pub fn parse_str(source: &str) -> core::result::Result { Frontend::new().parse(source) } diff --git a/naga/src/front/wgsl/parse/conv.rs b/naga/src/front/wgsl/parse/conv.rs index 00c19d877d..93ee0dfed2 100644 --- a/naga/src/front/wgsl/parse/conv.rs +++ b/naga/src/front/wgsl/parse/conv.rs @@ -1,8 +1,9 @@ -use super::Error; -use crate::front::wgsl::Scalar; +use crate::front::wgsl::{Error, Result, Scalar}; use crate::Span; -pub fn map_address_space(word: &str, span: Span) -> Result> { +use alloc::boxed::Box; + +pub fn map_address_space(word: &str, span: Span) -> Result<'_, crate::AddressSpace> { match word { "private" => Ok(crate::AddressSpace::Private), "workgroup" => Ok(crate::AddressSpace::WorkGroup), @@ -12,11 +13,11 @@ pub fn map_address_space(word: &str, span: Span) -> Result Ok(crate::AddressSpace::PushConstant), "function" => Ok(crate::AddressSpace::Function), - _ => Err(Error::UnknownAddressSpace(span)), + _ => Err(Box::new(Error::UnknownAddressSpace(span))), } } -pub fn map_built_in(word: &str, span: Span) -> Result> { +pub fn map_built_in(word: &str, span: Span) -> Result<'_, crate::BuiltIn> { Ok(match word { "position" => crate::BuiltIn::Position { invariant: false }, // vertex @@ -40,31 +41,31 @@ pub fn map_built_in(word: &str, span: Span) -> Result> "subgroup_id" => crate::BuiltIn::SubgroupId, "subgroup_size" => crate::BuiltIn::SubgroupSize, "subgroup_invocation_id" => crate::BuiltIn::SubgroupInvocationId, - _ => return Err(Error::UnknownBuiltin(span)), + _ => return Err(Box::new(Error::UnknownBuiltin(span))), }) } -pub fn map_interpolation(word: &str, span: Span) -> Result> { +pub fn map_interpolation(word: &str, span: Span) -> Result<'_, crate::Interpolation> { match word { "linear" => Ok(crate::Interpolation::Linear), "flat" => Ok(crate::Interpolation::Flat), "perspective" => Ok(crate::Interpolation::Perspective), - _ => Err(Error::UnknownAttribute(span)), + _ => Err(Box::new(Error::UnknownAttribute(span))), } } -pub fn map_sampling(word: &str, span: Span) -> Result> { +pub fn map_sampling(word: &str, span: Span) -> Result<'_, crate::Sampling> { match word { "center" => Ok(crate::Sampling::Center), "centroid" => Ok(crate::Sampling::Centroid), "sample" => Ok(crate::Sampling::Sample), "first" => Ok(crate::Sampling::First), "either" => Ok(crate::Sampling::Either), - _ => Err(Error::UnknownAttribute(span)), + _ => Err(Box::new(Error::UnknownAttribute(span))), } } -pub fn map_storage_format(word: &str, span: Span) -> Result> { +pub fn map_storage_format(word: &str, span: Span) -> Result<'_, crate::StorageFormat> { use crate::StorageFormat as Sf; Ok(match word { "r8unorm" => Sf::R8Unorm, @@ -108,7 +109,7 @@ pub fn map_storage_format(word: &str, span: Span) -> Result Sf::Rgba32Sint, "rgba32float" => Sf::Rgba32Float, "bgra8unorm" => Sf::Bgra8Unorm, - _ => return Err(Error::UnknownStorageFormat(span)), + _ => return Err(Box::new(Error::UnknownStorageFormat(span))), }) } @@ -261,16 +262,13 @@ pub fn map_standard_fun(word: &str) -> Option { }) } -pub fn map_conservative_depth( - word: &str, - span: Span, -) -> Result> { +pub fn map_conservative_depth(word: &str, span: Span) -> Result<'_, crate::ConservativeDepth> { use crate::ConservativeDepth as Cd; match word { "greater_equal" => Ok(Cd::GreaterEqual), "less_equal" => Ok(Cd::LessEqual), "unchanged" => Ok(Cd::Unchanged), - _ => Err(Error::UnknownConservativeDepth(span)), + _ => Err(Box::new(Error::UnknownConservativeDepth(span))), } } diff --git a/naga/src/front/wgsl/parse/directive.rs b/naga/src/front/wgsl/parse/directive.rs index 3a661bc585..1fed039364 100644 --- a/naga/src/front/wgsl/parse/directive.rs +++ b/naga/src/front/wgsl/parse/directive.rs @@ -5,6 +5,8 @@ pub mod enable_extension; pub(crate) mod language_extension; +use alloc::boxed::Box; + /// A parsed sentinel word indicating the type of directive to be parsed next. #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] #[cfg_attr(test, derive(strum::EnumIter))] @@ -37,9 +39,9 @@ impl crate::diagnostic_filter::Severity { #[cfg(feature = "wgsl-in")] pub(crate) fn report_wgsl_parse_diag<'a>( self, - err: crate::front::wgsl::error::Error<'a>, + err: Box>, source: &str, - ) -> Result<(), crate::front::wgsl::error::Error<'a>> { + ) -> crate::front::wgsl::Result<'a, ()> { self.report_diag(err, |e, level| { let e = e.as_parse_error(source); log::log!(level, "{}", e.emit_to_string(source)); diff --git a/naga/src/front/wgsl/parse/directive/enable_extension.rs b/naga/src/front/wgsl/parse/directive/enable_extension.rs index 6096417480..e4ad7e1399 100644 --- a/naga/src/front/wgsl/parse/directive/enable_extension.rs +++ b/naga/src/front/wgsl/parse/directive/enable_extension.rs @@ -2,7 +2,10 @@ //! //! The focal point of this module is the [`EnableExtension`] API. -use crate::{front::wgsl::error::Error, Span}; +use crate::front::wgsl::{Error, Result}; +use crate::Span; + +use alloc::boxed::Box; /// Tracks the status of every enable-extension known to Naga. #[derive(Clone, Debug, Eq, PartialEq)] @@ -61,7 +64,7 @@ impl EnableExtension { const DUAL_SOURCE_BLENDING: &'static str = "dual_source_blending"; /// Convert from a sentinel word in WGSL into its associated [`EnableExtension`], if possible. - pub(crate) fn from_ident(word: &str, span: Span) -> Result> { + pub(crate) fn from_ident(word: &str, span: Span) -> Result { Ok(match word { Self::F16 => Self::Unimplemented(UnimplementedEnableExtension::F16), Self::CLIP_DISTANCES => { @@ -70,7 +73,7 @@ impl EnableExtension { Self::DUAL_SOURCE_BLENDING => { Self::Implemented(ImplementedEnableExtension::DualSourceBlending) } - _ => return Err(Error::UnknownEnableExtension(span, word)), + _ => return Err(Box::new(Error::UnknownEnableExtension(span, word))), }) } diff --git a/naga/src/front/wgsl/parse/lexer.rs b/naga/src/front/wgsl/parse/lexer.rs index 12b4534617..374a1dbc98 100644 --- a/naga/src/front/wgsl/parse/lexer.rs +++ b/naga/src/front/wgsl/parse/lexer.rs @@ -1,10 +1,12 @@ -use super::{number::consume_number, Error, ExpectedToken}; +use super::{number::consume_number, Error, ExpectedToken, Result}; use crate::front::wgsl::error::NumberError; use crate::front::wgsl::parse::directive::enable_extension::EnableExtensions; use crate::front::wgsl::parse::{conv, Number}; use crate::front::wgsl::Scalar; use crate::Span; +use alloc::boxed::Box; + type TokenSpan<'a> = (Token<'a>, Span); #[derive(Copy, Clone, Debug, PartialEq)] @@ -12,7 +14,7 @@ pub enum Token<'a> { Separator(char), Paren(char), Attribute, - Number(Result), + Number(core::result::Result), Word(&'a str), Operation(char), LogicalOperation(char), @@ -242,8 +244,8 @@ impl<'a> Lexer<'a> { #[inline] pub fn capture_span( &mut self, - inner: impl FnOnce(&mut Self) -> Result, - ) -> Result<(T, Span), E> { + inner: impl FnOnce(&mut Self) -> core::result::Result, + ) -> core::result::Result<(T, Span), E> { let start = self.current_byte_offset(); let res = inner(self)?; let end = self.current_byte_offset(); @@ -319,19 +321,19 @@ impl<'a> Lexer<'a> { token } - pub(in crate::front::wgsl) fn expect_span( - &mut self, - expected: Token<'a>, - ) -> Result> { + pub(in crate::front::wgsl) fn expect_span(&mut self, expected: Token<'a>) -> Result<'a, Span> { let next = self.next(); if next.0 == expected { Ok(next.1) } else { - Err(Error::Unexpected(next.1, ExpectedToken::Token(expected))) + Err(Box::new(Error::Unexpected( + next.1, + ExpectedToken::Token(expected), + ))) } } - pub(in crate::front::wgsl) fn expect(&mut self, expected: Token<'a>) -> Result<(), Error<'a>> { + pub(in crate::front::wgsl) fn expect(&mut self, expected: Token<'a>) -> Result<'a, ()> { self.expect_span(expected)?; Ok(()) } @@ -339,15 +341,15 @@ impl<'a> Lexer<'a> { pub(in crate::front::wgsl) fn expect_generic_paren( &mut self, expected: char, - ) -> Result<(), Error<'a>> { + ) -> Result<'a, ()> { let next = self.next_generic(); if next.0 == Token::Paren(expected) { Ok(()) } else { - Err(Error::Unexpected( + Err(Box::new(Error::Unexpected( next.1, ExpectedToken::Token(Token::Paren(expected)), - )) + ))) } } @@ -366,50 +368,50 @@ impl<'a> Lexer<'a> { } } - pub(in crate::front::wgsl) fn next_ident_with_span( - &mut self, - ) -> Result<(&'a str, Span), Error<'a>> { + pub(in crate::front::wgsl) fn next_ident_with_span(&mut self) -> Result<'a, (&'a str, Span)> { match self.next() { (Token::Word(word), span) => Self::word_as_ident_with_span(word, span), - other => Err(Error::Unexpected(other.1, ExpectedToken::Identifier)), + other => Err(Box::new(Error::Unexpected( + other.1, + ExpectedToken::Identifier, + ))), } } - pub(in crate::front::wgsl) fn peek_ident_with_span( - &mut self, - ) -> Result<(&'a str, Span), Error<'a>> { + pub(in crate::front::wgsl) fn peek_ident_with_span(&mut self) -> Result<'a, (&'a str, Span)> { match self.peek() { (Token::Word(word), span) => Self::word_as_ident_with_span(word, span), - other => Err(Error::Unexpected(other.1, ExpectedToken::Identifier)), + other => Err(Box::new(Error::Unexpected( + other.1, + ExpectedToken::Identifier, + ))), } } - fn word_as_ident_with_span(word: &'a str, span: Span) -> Result<(&'a str, Span), Error<'a>> { + fn word_as_ident_with_span(word: &'a str, span: Span) -> Result<'a, (&'a str, Span)> { match word { - "_" => Err(Error::InvalidIdentifierUnderscore(span)), - word if word.starts_with("__") => Err(Error::ReservedIdentifierPrefix(span)), + "_" => Err(Box::new(Error::InvalidIdentifierUnderscore(span))), + word if word.starts_with("__") => Err(Box::new(Error::ReservedIdentifierPrefix(span))), word => Ok((word, span)), } } - pub(in crate::front::wgsl) fn next_ident( - &mut self, - ) -> Result, Error<'a>> { + pub(in crate::front::wgsl) fn next_ident(&mut self) -> Result<'a, super::ast::Ident<'a>> { self.next_ident_with_span() .and_then(|(word, span)| Self::word_as_ident(word, span)) .map(|(name, span)| super::ast::Ident { name, span }) } - fn word_as_ident(word: &'a str, span: Span) -> Result<(&'a str, Span), Error<'a>> { + fn word_as_ident(word: &'a str, span: Span) -> Result<'a, (&'a str, Span)> { if crate::keywords::wgsl::RESERVED.contains(&word) { - Err(Error::ReservedKeyword(span)) + Err(Box::new(Error::ReservedKeyword(span))) } else { Ok((word, span)) } } /// Parses a generic scalar type, for example ``. - pub(in crate::front::wgsl) fn next_scalar_generic(&mut self) -> Result> { + pub(in crate::front::wgsl) fn next_scalar_generic(&mut self) -> Result<'a, Scalar> { self.expect_generic_paren('<')?; let pair = match self.next() { (Token::Word(word), span) => { @@ -426,7 +428,7 @@ impl<'a> Lexer<'a> { /// Returns the span covering the inner type, excluding the brackets. pub(in crate::front::wgsl) fn next_scalar_generic_with_span( &mut self, - ) -> Result<(Scalar, Span), Error<'a>> { + ) -> Result<'a, (Scalar, Span)> { self.expect_generic_paren('<')?; let pair = match self.next() { (Token::Word(word), span) => conv::get_scalar_type(word) @@ -440,7 +442,7 @@ impl<'a> Lexer<'a> { pub(in crate::front::wgsl) fn next_storage_access( &mut self, - ) -> Result> { + ) -> Result<'a, crate::StorageAccess> { let (ident, span) = self.next_ident_with_span()?; match ident { "read" => Ok(crate::StorageAccess::LOAD), @@ -449,13 +451,13 @@ impl<'a> Lexer<'a> { "atomic" => Ok(crate::StorageAccess::ATOMIC | crate::StorageAccess::LOAD | crate::StorageAccess::STORE), - _ => Err(Error::UnknownAccess(span)), + _ => Err(Box::new(Error::UnknownAccess(span))), } } pub(in crate::front::wgsl) fn next_format_generic( &mut self, - ) -> Result<(crate::StorageFormat, crate::StorageAccess), Error<'a>> { + ) -> Result<'a, (crate::StorageFormat, crate::StorageAccess)> { self.expect(Token::Paren('<'))?; let (ident, ident_span) = self.next_ident_with_span()?; let format = conv::map_storage_format(ident, ident_span)?; @@ -465,16 +467,14 @@ impl<'a> Lexer<'a> { Ok((format, access)) } - pub(in crate::front::wgsl) fn next_acceleration_structure_flags( - &mut self, - ) -> Result> { + pub(in crate::front::wgsl) fn next_acceleration_structure_flags(&mut self) -> Result<'a, bool> { Ok(if self.skip(Token::Paren('<')) { if !self.skip(Token::Paren('>')) { let (name, span) = self.next_ident_with_span()?; let ret = if name == "vertex_return" { true } else { - return Err(Error::UnknownAttribute(span)); + return Err(Box::new(Error::UnknownAttribute(span))); }; self.skip(Token::Separator(',')); self.expect(Token::Paren('>'))?; @@ -487,16 +487,16 @@ impl<'a> Lexer<'a> { }) } - pub(in crate::front::wgsl) fn open_arguments(&mut self) -> Result<(), Error<'a>> { + pub(in crate::front::wgsl) fn open_arguments(&mut self) -> Result<'a, ()> { self.expect(Token::Paren('(')) } - pub(in crate::front::wgsl) fn close_arguments(&mut self) -> Result<(), Error<'a>> { + pub(in crate::front::wgsl) fn close_arguments(&mut self) -> Result<'a, ()> { let _ = self.skip(Token::Separator(',')); self.expect(Token::Paren(')')) } - pub(in crate::front::wgsl) fn next_argument(&mut self) -> Result> { + pub(in crate::front::wgsl) fn next_argument(&mut self) -> Result<'a, bool> { let paren = Token::Paren(')'); if self.skip(Token::Separator(',')) { Ok(!self.skip(paren)) diff --git a/naga/src/front/wgsl/parse/mod.rs b/naga/src/front/wgsl/parse/mod.rs index 6b9be15312..ce02f93b31 100644 --- a/naga/src/front/wgsl/parse/mod.rs +++ b/naga/src/front/wgsl/parse/mod.rs @@ -13,7 +13,7 @@ use crate::front::wgsl::parse::directive::language_extension::LanguageExtension; use crate::front::wgsl::parse::directive::DirectiveKind; use crate::front::wgsl::parse::lexer::{Lexer, Token}; use crate::front::wgsl::parse::number::Number; -use crate::front::wgsl::Scalar; +use crate::front::wgsl::{Result, Scalar}; use crate::front::SymbolTable; use crate::{Arena, FastHashSet, FastIndexSet, Handle, ShaderStage, Span}; @@ -95,11 +95,8 @@ impl<'a> ExpressionContext<'a, '_, '_> { &mut self, lexer: &mut Lexer<'a>, classifier: impl Fn(Token<'a>) -> Option, - mut parser: impl FnMut( - &mut Lexer<'a>, - &mut Self, - ) -> Result>, Error<'a>>, - ) -> Result>, Error<'a>> { + mut parser: impl FnMut(&mut Lexer<'a>, &mut Self) -> Result<'a, Handle>>, + ) -> Result<'a, Handle>> { let start = lexer.start_byte_offset(); let mut accumulator = parser(lexer, self)?; while let Some(op) = classifier(lexer.peek().0) { @@ -114,13 +111,13 @@ impl<'a> ExpressionContext<'a, '_, '_> { Ok(accumulator) } - fn declare_local(&mut self, name: ast::Ident<'a>) -> Result, Error<'a>> { + fn declare_local(&mut self, name: ast::Ident<'a>) -> Result<'a, Handle> { let handle = self.locals.append(ast::Local, name.span); if let Some(old) = self.local_table.add(name.name, handle) { - Err(Error::Redefinition { + Err(Box::new(Error::Redefinition { previous: self.locals.get_span(old), current: name.span, - }) + })) } else { Ok(handle) } @@ -166,9 +163,9 @@ impl Default for ParsedAttribute { } impl ParsedAttribute { - fn set(&mut self, value: T, name_span: Span) -> Result<(), Error<'static>> { + fn set(&mut self, value: T, name_span: Span) -> Result<'static, ()> { if self.value.is_some() { - return Err(Error::RepeatedAttribute(name_span)); + return Err(Box::new(Error::RepeatedAttribute(name_span))); } self.value = Some(value); Ok(()) @@ -193,7 +190,7 @@ impl<'a> BindingParser<'a> { name: &'a str, name_span: Span, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result<(), Error<'a>> { + ) -> Result<'a, ()> { match name { "location" => { lexer.expect(Token::Paren('('))?; @@ -229,10 +226,10 @@ impl<'a> BindingParser<'a> { .enable_extensions .contains(ImplementedEnableExtension::DualSourceBlending) { - return Err(Error::EnableExtensionNotEnabled { + return Err(Box::new(Error::EnableExtensionNotEnabled { span: name_span, kind: ImplementedEnableExtension::DualSourceBlending.into(), - }); + })); } lexer.expect(Token::Paren('('))?; @@ -240,12 +237,12 @@ impl<'a> BindingParser<'a> { .set(parser.general_expression(lexer, ctx)?, name_span)?; lexer.expect(Token::Paren(')'))?; } - _ => return Err(Error::UnknownAttribute(name_span)), + _ => return Err(Box::new(Error::UnknownAttribute(name_span))), } Ok(()) } - fn finish(self, span: Span) -> Result>, Error<'a>> { + fn finish(self, span: Span) -> Result<'a, Option>> { match ( self.location.value, self.built_in.value, @@ -275,7 +272,7 @@ impl<'a> BindingParser<'a> { (None, Some(built_in), None, None, false, None) => { Ok(Some(ast::Binding::BuiltIn(built_in))) } - (_, _, _, _, _, _) => Err(Error::InconsistentBinding(span)), + (_, _, _, _, _, _) => Err(Box::new(Error::InconsistentBinding(span))), } } } @@ -322,13 +319,13 @@ impl Parser { ) } - fn track_recursion<'a, F, R>(&mut self, f: F) -> Result> + fn track_recursion<'a, F, R>(&mut self, f: F) -> Result<'a, R> where - F: FnOnce(&mut Self) -> Result>, + F: FnOnce(&mut Self) -> Result<'a, R>, { self.recursion_depth += 1; if self.recursion_depth >= 256 { - return Err(Error::Internal("Parser recursion limit exceeded")); + return Err(Box::new(Error::Internal("Parser recursion limit exceeded"))); } let ret = f(self); self.recursion_depth -= 1; @@ -339,7 +336,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result, Error<'a>> { + ) -> Result<'a, ast::SwitchValue<'a>> { if let Token::Word("default") = lexer.peek().0 { let _ = lexer.next(); return Ok(ast::SwitchValue::Default); @@ -366,7 +363,7 @@ impl Parser { word: &'a str, span: Span, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result>, Error<'a>> { + ) -> Result<'a, Option>> { if let Some(scalar) = conv::get_scalar_type(word) { return Ok(Some(ast::ConstructorType::Scalar(scalar))); } @@ -575,7 +572,7 @@ impl Parser { | "texture_storage_1d_array" | "texture_storage_2d" | "texture_storage_2d_array" - | "texture_storage_3d" => return Err(Error::TypeNotConstructible(span)), + | "texture_storage_3d" => return Err(Box::new(Error::TypeNotConstructible(span))), _ => return Ok(None), }; @@ -617,7 +614,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result>>, Error<'a>> { + ) -> Result<'a, Vec>>> { self.push_rule_span(Rule::EnclosedExpr, lexer); lexer.open_arguments()?; let mut arguments = Vec::new(); @@ -641,7 +638,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result>, Error<'a>> { + ) -> Result<'a, Handle>> { self.push_rule_span(Rule::EnclosedExpr, lexer); let expr = self.general_expression(lexer, ctx)?; self.pop_rule_span(lexer); @@ -656,7 +653,7 @@ impl Parser { name: &'a str, name_span: Span, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result>, Error<'a>> { + ) -> Result<'a, Handle>> { assert!(self.rules.last().is_some()); let expr = match name { @@ -718,7 +715,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result>, Error<'a>> { + ) -> Result<'a, Handle>> { self.push_rule_span(Rule::PrimaryExpr, lexer); const fn literal_ray_flag<'b>(flag: crate::RayFlag) -> ast::Expression<'b> { ast::Expression::Literal(ast::Literal::Number(Number::U32(flag.bits()))) @@ -841,7 +838,12 @@ impl Parser { ast::Expression::Ident(ident) } } - other => return Err(Error::Unexpected(other.1, ExpectedToken::PrimaryExpression)), + other => { + return Err(Box::new(Error::Unexpected( + other.1, + ExpectedToken::PrimaryExpression, + ))) + } }; let span = self.pop_rule_span(lexer); @@ -855,7 +857,7 @@ impl Parser { lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, expr: Handle>, - ) -> Result>, Error<'a>> { + ) -> Result<'a, Handle>> { let mut expr = expr; loop { @@ -887,7 +889,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result>, Error<'a>> { + ) -> Result<'a, Handle>> { self.push_rule_span(Rule::GenericExpr, lexer); let expr = self.general_expression(lexer, ctx)?; self.pop_rule_span(lexer); @@ -899,7 +901,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result>, Error<'a>> { + ) -> Result<'a, Handle>> { self.track_recursion(|this| { this.push_rule_span(Rule::UnaryExpr, lexer); //TODO: refactor this to avoid backing up @@ -964,7 +966,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result>, Error<'a>> { + ) -> Result<'a, Handle>> { self.track_recursion(|this| { this.push_rule_span(Rule::LhsExpr, lexer); let start = lexer.start_byte_offset(); @@ -1008,7 +1010,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result>, Error<'a>> { + ) -> Result<'a, Handle>> { let start = lexer.start_byte_offset(); self.push_rule_span(Rule::SingularExpr, lexer); let primary_expr = self.primary_expression(lexer, ctx)?; @@ -1022,7 +1024,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, context: &mut ExpressionContext<'a, '_, '_>, - ) -> Result>, Error<'a>> { + ) -> Result<'a, Handle>> { // equality_expression context.parse_binary_op( lexer, @@ -1115,7 +1117,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result>, Error<'a>> { + ) -> Result<'a, Handle>> { self.general_expression_with_span(lexer, ctx) .map(|(expr, _)| expr) } @@ -1124,7 +1126,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, context: &mut ExpressionContext<'a, '_, '_>, - ) -> Result<(Handle>, Span), Error<'a>> { + ) -> Result<'a, (Handle>, Span)> { self.push_rule_span(Rule::GeneralExpr, lexer); // logical_or_expression let handle = context.parse_binary_op( @@ -1188,7 +1190,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result, Error<'a>> { + ) -> Result<'a, ast::GlobalVariable<'a>> { self.push_rule_span(Rule::VariableDecl, lexer); let mut space = crate::AddressSpace::Handle; @@ -1238,7 +1240,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result>, Error<'a>> { + ) -> Result<'a, Vec>> { let mut members = Vec::new(); let mut member_names = FastHashSet::default(); @@ -1246,10 +1248,10 @@ impl Parser { let mut ready = true; while !lexer.skip(Token::Paren('}')) { if !ready { - return Err(Error::Unexpected( + return Err(Box::new(Error::Unexpected( lexer.next().1, ExpectedToken::Token(Token::Separator(',')), - )); + ))); } let (mut size, mut align) = (ParsedAttribute::default(), ParsedAttribute::default()); self.push_rule_span(Rule::Attribute, lexer); @@ -1289,14 +1291,14 @@ impl Parser { }); if !member_names.insert(name.name) { - return Err(Error::Redefinition { + return Err(Box::new(Error::Redefinition { previous: members .iter() .find(|x| x.name.name == name.name) .map(|x| x.name.span) .unwrap(), current: name.span, - }); + })); } } @@ -1308,7 +1310,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result<(Handle>, Span), Error<'a>> { + ) -> Result<'a, (Handle>, Span)> { lexer.expect_generic_paren('<')?; let start = lexer.start_byte_offset(); let ty = self.type_decl(lexer, ctx)?; @@ -1324,7 +1326,7 @@ impl Parser { ctx: &mut ExpressionContext<'a, '_, '_>, columns: crate::VectorSize, rows: crate::VectorSize, - ) -> Result, Error<'a>> { + ) -> Result<'a, ast::Type<'a>> { let (ty, ty_span) = self.singular_generic(lexer, ctx)?; Ok(ast::Type::Matrix { columns, @@ -1339,7 +1341,7 @@ impl Parser { lexer: &mut Lexer<'a>, word: &'a str, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result>, Error<'a>> { + ) -> Result<'a, Option>> { if let Some(scalar) = conv::get_scalar_type(word) { return Ok(Some(ast::Type::Scalar(scalar))); } @@ -1734,7 +1736,7 @@ impl Parser { })) } - const fn check_texture_sample_type(scalar: Scalar, span: Span) -> Result<(), Error<'static>> { + fn check_texture_sample_type(scalar: Scalar, span: Span) -> Result<'static, ()> { use crate::ScalarKind::*; // Validate according to https://gpuweb.github.io/gpuweb/wgsl/#sampled-texture-type match scalar { @@ -1746,7 +1748,7 @@ impl Parser { kind: Uint, width: 8, } => Ok(()), - _ => Err(Error::BadTextureSampleType { span, scalar }), + _ => Err(Box::new(Error::BadTextureSampleType { span, scalar })), } } @@ -1755,7 +1757,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result>, Error<'a>> { + ) -> Result<'a, Handle>> { self.track_recursion(|this| { this.push_rule_span(Rule::TypeDecl, lexer); @@ -1786,7 +1788,7 @@ impl Parser { block: &mut ast::Block<'a>, target: Handle>, span_start: usize, - ) -> Result<(), Error<'a>> { + ) -> Result<'a, ()> { use crate::BinaryOperator as Bo; let op = lexer.next(); @@ -1828,7 +1830,7 @@ impl Parser { }); return Ok(()); } - _ => return Err(Error::Unexpected(op.1, ExpectedToken::Assignment)), + _ => return Err(Box::new(Error::Unexpected(op.1, ExpectedToken::Assignment))), }; let span = lexer.span_from(span_start); @@ -1845,7 +1847,7 @@ impl Parser { lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, block: &mut ast::Block<'a>, - ) -> Result<(), Error<'a>> { + ) -> Result<'a, ()> { let span_start = lexer.start_byte_offset(); let target = self.lhs_expression(lexer, ctx)?; self.assignment_op_and_rhs(lexer, ctx, block, target, span_start) @@ -1861,7 +1863,7 @@ impl Parser { span_start: usize, context: &mut ExpressionContext<'a, '_, '_>, block: &mut ast::Block<'a>, - ) -> Result<(), Error<'a>> { + ) -> Result<'a, ()> { self.push_rule_span(Rule::SingularExpr, lexer); context.unresolved.insert(ast::Dependency { @@ -1892,7 +1894,7 @@ impl Parser { lexer: &mut Lexer<'a>, context: &mut ExpressionContext<'a, '_, '_>, block: &mut ast::Block<'a>, - ) -> Result<(), Error<'a>> { + ) -> Result<'a, ()> { let span_start = lexer.start_byte_offset(); match lexer.peek() { (Token::Word(name), span) => { @@ -1919,7 +1921,7 @@ impl Parser { ctx: &mut ExpressionContext<'a, '_, '_>, block: &mut ast::Block<'a>, brace_nesting_level: u8, - ) -> Result<(), Error<'a>> { + ) -> Result<'a, ()> { self.track_recursion(|this| { this.push_rule_span(Rule::Statement, lexer); match lexer.peek() { @@ -2126,10 +2128,10 @@ impl Parser { } (Token::Paren('}'), _) => break, (_, span) => { - return Err(Error::Unexpected( + return Err(Box::new(Error::Unexpected( span, ExpectedToken::SwitchItem, - )) + ))) } } } @@ -2191,7 +2193,11 @@ impl Parser { ast::StatementKind::Call { .. } | ast::StatementKind::Assign { .. } | ast::StatementKind::LocalDecl(_) => {} - _ => return Err(Error::InvalidForInitializer(span)), + _ => { + return Err(Box::new(Error::InvalidForInitializer( + span, + ))) + } } } }; @@ -2199,7 +2205,7 @@ impl Parser { let mut body = ast::Block::default(); if !lexer.skip(Token::Separator(';')) { let (condition, span) = - lexer.capture_span(|lexer| -> Result<_, Error<'_>> { + lexer.capture_span(|lexer| -> Result<'_, _> { let condition = this.general_expression(lexer, ctx)?; lexer.expect(Token::Separator(';'))?; Ok(condition) @@ -2251,7 +2257,7 @@ impl Parser { let (peeked_token, peeked_span) = lexer.peek(); if let Token::Word("if") = peeked_token { let span = span.until(&peeked_span); - return Err(Error::InvalidBreakIf(span)); + return Err(Box::new(Error::InvalidBreakIf(span))); } lexer.expect(Token::Separator(';'))?; ast::StatementKind::Break @@ -2307,7 +2313,7 @@ impl Parser { lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, brace_nesting_level: u8, - ) -> Result, Error<'a>> { + ) -> Result<'a, ast::StatementKind<'a>> { let _ = lexer.next(); let mut body = ast::Block::default(); let mut continuing = ast::Block::default(); @@ -2387,7 +2393,7 @@ impl Parser { lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, brace_nesting_level: u8, - ) -> Result<(ast::Block<'a>, Span), Error<'a>> { + ) -> Result<'a, (ast::Block<'a>, Span)> { self.push_rule_span(Rule::Block, lexer); ctx.local_table.push_scope(); @@ -2400,21 +2406,25 @@ impl Parser { if let Some(DirectiveKind::Diagnostic) = DirectiveKind::from_ident(name) { let filter = self.diagnostic_filter(lexer)?; let span = self.peek_rule_span(lexer); - diagnostic_filters.add(filter, span, ShouldConflictOnFullDuplicate::Yes)?; + diagnostic_filters + .add(filter, span, ShouldConflictOnFullDuplicate::Yes) + .map_err(|e| Box::new(e.into()))?; } else { - return Err(Error::Unexpected( + return Err(Box::new(Error::Unexpected( name_span, ExpectedToken::DiagnosticAttribute, - )); + ))); } } self.pop_rule_span(lexer); if !diagnostic_filters.is_empty() { - return Err(Error::DiagnosticAttributeNotYetImplementedAtParseSite { - site_name_plural: "compound statements", - spans: diagnostic_filters.spans().collect(), - }); + return Err(Box::new( + Error::DiagnosticAttributeNotYetImplementedAtParseSite { + site_name_plural: "compound statements", + spans: diagnostic_filters.spans().collect(), + }, + )); } let brace_span = lexer.expect_span(Token::Paren('{'))?; @@ -2434,7 +2444,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, ctx: &mut ExpressionContext<'a, '_, '_>, - ) -> Result>, Error<'a>> { + ) -> Result<'a, Option>> { let mut bind_parser = BindingParser::default(); self.push_rule_span(Rule::Attribute, lexer); @@ -2454,7 +2464,7 @@ impl Parser { must_use: Option, out: &mut ast::TranslationUnit<'a>, dependencies: &mut FastIndexSet>, - ) -> Result, Error<'a>> { + ) -> Result<'a, ast::Function<'a>> { self.push_rule_span(Rule::FunctionDecl, lexer); // read function name let fun_name = lexer.next_ident()?; @@ -2478,10 +2488,10 @@ impl Parser { let mut ready = true; while !lexer.skip(Token::Paren(')')) { if !ready { - return Err(Error::Unexpected( + return Err(Box::new(Error::Unexpected( lexer.next().1, ExpectedToken::Token(Token::Separator(',')), - )); + ))); } let binding = self.varying_binding(lexer, &mut ctx)?; @@ -2510,10 +2520,10 @@ impl Parser { must_use, }) } else if let Some(must_use) = must_use { - return Err(Error::FunctionMustUseReturnsVoid( + return Err(Box::new(Error::FunctionMustUseReturnsVoid( must_use, self.peek_rule_span(lexer), - )); + ))); } else { None }; @@ -2546,8 +2556,8 @@ impl Parser { fn directive_ident_list<'a>( &self, lexer: &mut Lexer<'a>, - handler: impl FnMut(&'a str, Span) -> Result<(), Error<'a>>, - ) -> Result<(), Error<'a>> { + handler: impl FnMut(&'a str, Span) -> Result<'a, ()>, + ) -> Result<'a, ()> { let mut handler = handler; 'next_arg: loop { let (ident, span) = lexer.next_ident_with_span()?; @@ -2565,7 +2575,7 @@ impl Parser { }; if !matches!(lexer.next().0, Token::Separator(';')) { - return Err(Error::Unexpected(span, expected_token)); + return Err(Box::new(Error::Unexpected(span, expected_token))); } break Ok(()); @@ -2576,7 +2586,7 @@ impl Parser { &mut self, lexer: &mut Lexer<'a>, out: &mut ast::TranslationUnit<'a>, - ) -> Result<(), Error<'a>> { + ) -> Result<'a, ()> { // read attributes let mut binding = None; let mut stage = ParsedAttribute::default(); @@ -2598,14 +2608,14 @@ impl Parser { unresolved: &mut dependencies, }; let mut diagnostic_filters = DiagnosticFilterMap::new(); - let ensure_no_diag_attrs = |on_what, filters: DiagnosticFilterMap| -> Result<(), Error> { + let ensure_no_diag_attrs = |on_what, filters: DiagnosticFilterMap| -> Result<()> { if filters.is_empty() { Ok(()) } else { - Err(Error::DiagnosticAttributeNotSupported { + Err(Box::new(Error::DiagnosticAttributeNotSupported { on_what, spans: filters.spans().collect(), - }) + })) } }; @@ -2615,7 +2625,9 @@ impl Parser { if let Some(DirectiveKind::Diagnostic) = DirectiveKind::from_ident(name) { let filter = self.diagnostic_filter(lexer)?; let span = self.peek_rule_span(lexer); - diagnostic_filters.add(filter, span, ShouldConflictOnFullDuplicate::Yes)?; + diagnostic_filters + .add(filter, span, ShouldConflictOnFullDuplicate::Yes) + .map_err(|e| Box::new(e.into()))?; continue; } match name { @@ -2653,10 +2665,10 @@ impl Parser { (Token::Paren(')'), _) => break, (Token::Separator(','), _) if i != 2 => (), other => { - return Err(Error::Unexpected( + return Err(Box::new(Error::Unexpected( other.1, ExpectedToken::WorkgroupSizeSeparator, - )) + ))) } } } @@ -2676,7 +2688,7 @@ impl Parser { "must_use" => { must_use.set(name_span, name_span)?; } - _ => return Err(Error::UnknownAttribute(name_span)), + _ => return Err(Box::new(Error::UnknownAttribute(name_span))), } } @@ -2688,8 +2700,10 @@ impl Parser { binding: index, }); } - (Some(_), None) => return Err(Error::MissingAttribute("binding", attrib_span)), - (None, Some(_)) => return Err(Error::MissingAttribute("group", attrib_span)), + (Some(_), None) => { + return Err(Box::new(Error::MissingAttribute("binding", attrib_span))) + } + (None, Some(_)) => return Err(Box::new(Error::MissingAttribute("group", attrib_span))), (None, None) => {} } @@ -2704,7 +2718,9 @@ impl Parser { None } (Token::Word(word), directive_span) if DirectiveKind::from_ident(word).is_some() => { - return Err(Error::DirectiveAfterFirstGlobalDecl { directive_span }); + return Err(Box::new(Error::DirectiveAfterFirstGlobalDecl { + directive_span, + })); } (Token::Word("struct"), _) => { ensure_no_diag_attrs("`struct`s".into(), diagnostic_filters)?; @@ -2792,7 +2808,7 @@ impl Parser { Some(ast::GlobalDeclKind::Fn(ast::Function { entry_point: if let Some(stage) = stage.value { if stage == ShaderStage::Compute && workgroup_size.value.is_none() { - return Err(Error::MissingWorkgroupSize(compute_span)); + return Err(Box::new(Error::MissingWorkgroupSize(compute_span))); } Some(ast::EntryPoint { stage, @@ -2820,7 +2836,12 @@ impl Parser { Some(ast::GlobalDeclKind::ConstAssert(condition)) } (Token::End, _) => return Ok(()), - other => return Err(Error::Unexpected(other.1, ExpectedToken::GlobalItem)), + other => { + return Err(Box::new(Error::Unexpected( + other.1, + ExpectedToken::GlobalItem, + ))) + } }; if let Some(kind) = kind { @@ -2833,16 +2854,18 @@ impl Parser { if !self.rules.is_empty() { log::error!("Reached the end of global decl, but rule stack is not empty"); log::error!("Rules: {:?}", self.rules); - return Err(Error::Internal("rule stack is not empty")); + return Err(Box::new(Error::Internal("rule stack is not empty"))); }; match binding { None => Ok(()), - Some(_) => Err(Error::Internal("we had the attribute but no var?")), + Some(_) => Err(Box::new(Error::Internal( + "we had the attribute but no var?", + ))), } } - pub fn parse<'a>(&mut self, source: &'a str) -> Result, Error<'a>> { + pub fn parse<'a>(&mut self, source: &'a str) -> Result<'a, ast::TranslationUnit<'a>> { self.reset(); let mut lexer = Lexer::new(source); @@ -2859,11 +2882,9 @@ impl Parser { DirectiveKind::Diagnostic => { let diagnostic_filter = self.diagnostic_filter(&mut lexer)?; let span = self.peek_rule_span(&lexer); - diagnostic_filters.add( - diagnostic_filter, - span, - ShouldConflictOnFullDuplicate::No, - )?; + diagnostic_filters + .add(diagnostic_filter, span, ShouldConflictOnFullDuplicate::No) + .map_err(|e| Box::new(e.into()))?; lexer.expect(Token::Separator(';'))?; } DirectiveKind::Enable => { @@ -2872,10 +2893,10 @@ impl Parser { let extension = match kind { EnableExtension::Implemented(kind) => kind, EnableExtension::Unimplemented(kind) => { - return Err(Error::EnableExtensionNotYetImplemented { + return Err(Box::new(Error::EnableExtensionNotYetImplemented { kind, span, - }) + })) } }; enable_extensions.add(extension); @@ -2893,9 +2914,12 @@ impl Parser { Ok(()) } Some(LanguageExtension::Unimplemented(kind)) => { - Err(Error::LanguageExtensionNotYetImplemented { kind, span }) + Err(Box::new(Error::LanguageExtensionNotYetImplemented { + kind, + span, + })) } - None => Err(Error::UnknownLanguageExtension(span, ident)), + None => Err(Box::new(Error::UnknownLanguageExtension(span, ident))), } })?; } @@ -2925,10 +2949,7 @@ impl Parser { Ok(tu) } - const fn increase_brace_nesting( - brace_nesting_level: u8, - brace_span: Span, - ) -> Result> { + fn increase_brace_nesting(brace_nesting_level: u8, brace_span: Span) -> Result<'static, u8> { // From [spec.](https://gpuweb.github.io/gpuweb/wgsl/#limits): // // > ยง 2.4. Limits @@ -2943,15 +2964,15 @@ impl Parser { // const BRACE_NESTING_MAXIMUM: u8 = 64; if brace_nesting_level + 1 > BRACE_NESTING_MAXIMUM { - return Err(Error::ExceededLimitForNestedBraces { + return Err(Box::new(Error::ExceededLimitForNestedBraces { span: brace_span, limit: BRACE_NESTING_MAXIMUM, - }); + })); } Ok(brace_nesting_level + 1) } - fn diagnostic_filter<'a>(&self, lexer: &mut Lexer<'a>) -> Result> { + fn diagnostic_filter<'a>(&self, lexer: &mut Lexer<'a>) -> Result<'a, DiagnosticFilter> { lexer.expect(Token::Paren('('))?; let (severity_control_name, severity_control_name_span) = lexer.next_ident_with_span()?; @@ -2975,7 +2996,7 @@ impl Parser { FilterableTriggeringRule::Standard(triggering_rule) } else { diagnostic_filter::Severity::Warning.report_wgsl_parse_diag( - Error::UnknownDiagnosticRuleName(diagnostic_rule_name_span), + Box::new(Error::UnknownDiagnosticRuleName(diagnostic_rule_name_span)), lexer.source, )?; FilterableTriggeringRule::Unknown(diagnostic_rule_name.into()) diff --git a/naga/src/front/wgsl/tests.rs b/naga/src/front/wgsl/tests.rs index a0e1d7a3cc..bdcd35d8a8 100644 --- a/naga/src/front/wgsl/tests.rs +++ b/naga/src/front/wgsl/tests.rs @@ -684,7 +684,7 @@ fn parse_repeated_attributes() { let result = Frontend::new().inner(&shader); assert!(matches!( - result.unwrap_err(), + *result.unwrap_err(), Error::RepeatedAttribute(span) if span == expected_span )); } @@ -700,7 +700,7 @@ fn parse_missing_workgroup_size() { let shader = "@compute fn vs() -> vec4 { return vec4(0.0); }"; let result = Frontend::new().inner(shader); assert!(matches!( - result.unwrap_err(), + *result.unwrap_err(), Error::MissingWorkgroupSize(span) if span == Span::new(1, 8) )); }