mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-21 22:33:49 +00:00
Reduce size of parse error
This commit is contained in:
parent
a93dcb646a
commit
c7e5d07dee
@ -10,6 +10,9 @@ use std::ops::Range;
|
||||
use termcolor::{ColorChoice, NoColor, StandardStream};
|
||||
use thiserror::Error;
|
||||
|
||||
#[cfg(test)]
|
||||
use std::mem::size_of;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ParseError {
|
||||
message: String,
|
||||
@ -144,7 +147,7 @@ pub enum InvalidAssignmentType {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Error<'a> {
|
||||
pub(crate) enum Error<'a> {
|
||||
Unexpected(Span, ExpectedToken<'a>),
|
||||
UnexpectedComponents(Span),
|
||||
UnexpectedOperationInConstContext(Span),
|
||||
@ -154,8 +157,8 @@ pub enum Error<'a> {
|
||||
BadTexture(Span),
|
||||
BadTypeCast {
|
||||
span: Span,
|
||||
from_type: String,
|
||||
to_type: String,
|
||||
from_type: Box<str>,
|
||||
to_type: Box<str>,
|
||||
},
|
||||
BadTextureSampleType {
|
||||
span: Span,
|
||||
@ -188,8 +191,8 @@ pub enum Error<'a> {
|
||||
TypeNotInferable(Span),
|
||||
InitializationTypeMismatch {
|
||||
name: Span,
|
||||
expected: String,
|
||||
got: String,
|
||||
expected: Box<str>,
|
||||
got: Box<str>,
|
||||
},
|
||||
DeclMissingTypeAndInit(Span),
|
||||
MissingAttribute(&'static str, Span),
|
||||
@ -232,7 +235,7 @@ pub enum Error<'a> {
|
||||
/// name is `decl` has an identifier at `reference` whose definition is
|
||||
/// the next declaration in the cycle. The last pair's `reference` is
|
||||
/// the same identifier as `ident`, above.
|
||||
path: Vec<(Span, Span)>,
|
||||
path: Box<[(Span, Span)]>,
|
||||
},
|
||||
InvalidSwitchValue {
|
||||
uint: bool,
|
||||
@ -251,25 +254,10 @@ pub enum Error<'a> {
|
||||
ExpectedNonNegative(Span),
|
||||
ExpectedPositiveArrayLength(Span),
|
||||
MissingWorkgroupSize(Span),
|
||||
ConstantEvaluatorError(ConstantEvaluatorError, Span),
|
||||
AutoConversion {
|
||||
dest_span: Span,
|
||||
dest_type: String,
|
||||
source_span: Span,
|
||||
source_type: String,
|
||||
},
|
||||
AutoConversionLeafScalar {
|
||||
dest_span: Span,
|
||||
dest_scalar: String,
|
||||
source_span: Span,
|
||||
source_type: String,
|
||||
},
|
||||
ConcretizationFailed {
|
||||
expr_span: Span,
|
||||
expr_type: String,
|
||||
scalar: String,
|
||||
inner: ConstantEvaluatorError,
|
||||
},
|
||||
ConstantEvaluatorError(Box<ConstantEvaluatorError>, Span),
|
||||
AutoConversion(Box<AutoConversionError>),
|
||||
AutoConversionLeafScalar(Box<AutoConversionLeafScalarError>),
|
||||
ConcretizationFailed(Box<ConcretizationFailedError>),
|
||||
ExceededLimitForNestedBraces {
|
||||
span: Span,
|
||||
limit: u8,
|
||||
@ -277,6 +265,30 @@ pub enum Error<'a> {
|
||||
PipelineConstantIDValue(Span),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct AutoConversionError {
|
||||
pub dest_span: Span,
|
||||
pub dest_type: Box<str>,
|
||||
pub source_span: Span,
|
||||
pub source_type: Box<str>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct AutoConversionLeafScalarError {
|
||||
pub dest_span: Span,
|
||||
pub dest_scalar: Box<str>,
|
||||
pub source_span: Span,
|
||||
pub source_type: Box<str>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct ConcretizationFailedError {
|
||||
pub expr_span: Span,
|
||||
pub expr_type: Box<str>,
|
||||
pub scalar: Box<str>,
|
||||
pub inner: ConstantEvaluatorError,
|
||||
}
|
||||
|
||||
impl<'a> Error<'a> {
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
@ -738,45 +750,55 @@ impl<'a> Error<'a> {
|
||||
)],
|
||||
notes: vec![],
|
||||
},
|
||||
Error::AutoConversion { dest_span, ref dest_type, source_span, ref source_type } => ParseError {
|
||||
message: format!("automatic conversions cannot convert `{source_type}` to `{dest_type}`"),
|
||||
labels: vec![
|
||||
(
|
||||
dest_span,
|
||||
format!("a value of type {dest_type} is required here").into(),
|
||||
),
|
||||
(
|
||||
source_span,
|
||||
format!("this expression has type {source_type}").into(),
|
||||
)
|
||||
],
|
||||
notes: vec![],
|
||||
Error::AutoConversion(ref error) => {
|
||||
// destructuring ensures all fields are handled
|
||||
let AutoConversionError { dest_span, ref dest_type, source_span, ref source_type } = **error;
|
||||
ParseError {
|
||||
message: format!("automatic conversions cannot convert `{source_type}` to `{dest_type}`"),
|
||||
labels: vec![
|
||||
(
|
||||
dest_span,
|
||||
format!("a value of type {dest_type} is required here").into(),
|
||||
),
|
||||
(
|
||||
source_span,
|
||||
format!("this expression has type {source_type}").into(),
|
||||
)
|
||||
],
|
||||
notes: vec![],
|
||||
}
|
||||
},
|
||||
Error::AutoConversionLeafScalar { dest_span, ref dest_scalar, source_span, ref source_type } => ParseError {
|
||||
message: format!("automatic conversions cannot convert elements of `{source_type}` to `{dest_scalar}`"),
|
||||
labels: vec![
|
||||
(
|
||||
dest_span,
|
||||
format!("a value with elements of type {dest_scalar} is required here").into(),
|
||||
),
|
||||
(
|
||||
source_span,
|
||||
format!("this expression has type {source_type}").into(),
|
||||
)
|
||||
],
|
||||
notes: vec![],
|
||||
Error::AutoConversionLeafScalar(ref error) => {
|
||||
let AutoConversionLeafScalarError { dest_span, ref dest_scalar, source_span, ref source_type } = **error;
|
||||
ParseError {
|
||||
message: format!("automatic conversions cannot convert elements of `{source_type}` to `{dest_scalar}`"),
|
||||
labels: vec![
|
||||
(
|
||||
dest_span,
|
||||
format!("a value with elements of type {dest_scalar} is required here").into(),
|
||||
),
|
||||
(
|
||||
source_span,
|
||||
format!("this expression has type {source_type}").into(),
|
||||
)
|
||||
],
|
||||
notes: vec![],
|
||||
}
|
||||
},
|
||||
Error::ConcretizationFailed { expr_span, ref expr_type, ref scalar, ref inner } => ParseError {
|
||||
message: format!("failed to convert expression to a concrete type: {}", inner),
|
||||
labels: vec![
|
||||
(
|
||||
expr_span,
|
||||
format!("this expression has type {}", expr_type).into(),
|
||||
)
|
||||
],
|
||||
notes: vec![
|
||||
format!("the expression should have been converted to have {} scalar type", scalar),
|
||||
]
|
||||
Error::ConcretizationFailed(ref error) => {
|
||||
let ConcretizationFailedError { expr_span, ref expr_type, ref scalar, ref inner } = **error;
|
||||
ParseError {
|
||||
message: format!("failed to convert expression to a concrete type: {}", inner),
|
||||
labels: vec![
|
||||
(
|
||||
expr_span,
|
||||
format!("this expression has type {}", expr_type).into(),
|
||||
)
|
||||
],
|
||||
notes: vec![
|
||||
format!("the expression should have been converted to have {} scalar type", scalar),
|
||||
]
|
||||
}
|
||||
},
|
||||
Error::ExceededLimitForNestedBraces { span, limit } => ParseError {
|
||||
message: "brace nesting limit reached".into(),
|
||||
@ -796,3 +818,8 @@ impl<'a> Error<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_error_size() {
|
||||
assert!(size_of::<Error<'_>>() <= 48);
|
||||
}
|
||||
|
@ -530,11 +530,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
|
||||
// Bad conversion (type cast)
|
||||
(Components::One { span, ty_inner, .. }, constructor) => {
|
||||
let from_type = ty_inner.to_wgsl(&ctx.module.to_ctx());
|
||||
let from_type = ty_inner.to_wgsl(&ctx.module.to_ctx()).into();
|
||||
return Err(Error::BadTypeCast {
|
||||
span,
|
||||
from_type,
|
||||
to_type: constructor.to_error_string(ctx),
|
||||
to_type: constructor.to_error_string(ctx).into(),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
//! WGSL's automatic conversions for abstract types.
|
||||
|
||||
use crate::front::wgsl::error::{
|
||||
AutoConversionError, AutoConversionLeafScalarError, ConcretizationFailedError,
|
||||
};
|
||||
use crate::{Handle, Span};
|
||||
|
||||
impl<'source, 'temp, 'out> super::ExpressionContext<'source, 'temp, 'out> {
|
||||
@ -39,15 +42,17 @@ impl<'source, 'temp, 'out> super::ExpressionContext<'source, 'temp, 'out> {
|
||||
Some(scalars) => scalars,
|
||||
None => {
|
||||
let gctx = &self.module.to_ctx();
|
||||
let source_type = expr_resolution.to_wgsl(gctx);
|
||||
let dest_type = goal_ty.to_wgsl(gctx);
|
||||
let source_type = expr_resolution.to_wgsl(gctx).into();
|
||||
let dest_type = goal_ty.to_wgsl(gctx).into();
|
||||
|
||||
return Err(super::Error::AutoConversion {
|
||||
dest_span: goal_span,
|
||||
dest_type,
|
||||
source_span: expr_span,
|
||||
source_type,
|
||||
});
|
||||
return Err(super::Error::AutoConversion(Box::new(
|
||||
AutoConversionError {
|
||||
dest_span: goal_span,
|
||||
dest_type,
|
||||
source_span: expr_span,
|
||||
source_type,
|
||||
},
|
||||
)));
|
||||
}
|
||||
};
|
||||
|
||||
@ -79,13 +84,13 @@ impl<'source, 'temp, 'out> super::ExpressionContext<'source, 'temp, 'out> {
|
||||
|
||||
let make_error = || {
|
||||
let gctx = &self.module.to_ctx();
|
||||
let source_type = expr_resolution.to_wgsl(gctx);
|
||||
super::Error::AutoConversionLeafScalar {
|
||||
let source_type = expr_resolution.to_wgsl(gctx).into();
|
||||
super::Error::AutoConversionLeafScalar(Box::new(AutoConversionLeafScalarError {
|
||||
dest_span: goal_span,
|
||||
dest_scalar: goal_scalar.to_wgsl(),
|
||||
dest_scalar: goal_scalar.to_wgsl().into(),
|
||||
source_span: expr_span,
|
||||
source_type,
|
||||
}
|
||||
}))
|
||||
};
|
||||
|
||||
let expr_scalar = match expr_inner.scalar() {
|
||||
@ -116,7 +121,7 @@ impl<'source, 'temp, 'out> super::ExpressionContext<'source, 'temp, 'out> {
|
||||
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, expr_span))
|
||||
.map_err(|err| super::Error::ConstantEvaluatorError(err.into(), expr_span))
|
||||
} else {
|
||||
let cast = crate::Expression::As {
|
||||
expr,
|
||||
@ -254,12 +259,12 @@ impl<'source, 'temp, 'out> super::ExpressionContext<'source, 'temp, 'out> {
|
||||
// it has one. Also, avoid holding the borrow of `inner`
|
||||
// across the call to `cast_array`.
|
||||
let expr_type = &self.typifier()[expr];
|
||||
super::Error::ConcretizationFailed {
|
||||
super::Error::ConcretizationFailed(Box::new(ConcretizationFailedError {
|
||||
expr_span,
|
||||
expr_type: expr_type.to_wgsl(&self.module.to_ctx()),
|
||||
scalar: concretized.to_wgsl(),
|
||||
expr_type: expr_type.to_wgsl(&self.module.to_ctx()).into(),
|
||||
scalar: concretized.to_wgsl().into(),
|
||||
inner: err,
|
||||
}
|
||||
}))
|
||||
})?;
|
||||
}
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> {
|
||||
) -> Result<Handle<crate::Expression>, Error<'source>> {
|
||||
let mut eval = self.as_const_evaluator();
|
||||
eval.try_eval_and_append(expr, span)
|
||||
.map_err(|e| Error::ConstantEvaluatorError(e, span))
|
||||
.map_err(|e| Error::ConstantEvaluatorError(e.into(), span))
|
||||
}
|
||||
|
||||
fn const_access(&self, handle: Handle<crate::Expression>) -> Option<u32> {
|
||||
@ -945,15 +945,10 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
let converted = ectx
|
||||
.try_automatic_conversions(lowered, &ty_res, v.name.span)
|
||||
.map_err(|error| match error {
|
||||
Error::AutoConversion {
|
||||
dest_span: _,
|
||||
dest_type,
|
||||
source_span: _,
|
||||
source_type,
|
||||
} => Error::InitializationTypeMismatch {
|
||||
Error::AutoConversion(e) => Error::InitializationTypeMismatch {
|
||||
name: v.name.span,
|
||||
expected: dest_type,
|
||||
got: source_type,
|
||||
expected: e.dest_type,
|
||||
got: e.source_type,
|
||||
},
|
||||
other => other,
|
||||
})?;
|
||||
@ -997,15 +992,10 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
init = ectx
|
||||
.try_automatic_conversions(init, &explicit_ty_res, c.name.span)
|
||||
.map_err(|error| match error {
|
||||
Error::AutoConversion {
|
||||
dest_span: _,
|
||||
dest_type,
|
||||
source_span: _,
|
||||
source_type,
|
||||
} => Error::InitializationTypeMismatch {
|
||||
Error::AutoConversion(e) => Error::InitializationTypeMismatch {
|
||||
name: c.name.span,
|
||||
expected: dest_type,
|
||||
got: source_type,
|
||||
expected: e.dest_type,
|
||||
got: e.source_type,
|
||||
},
|
||||
other => other,
|
||||
})?;
|
||||
@ -1061,8 +1051,8 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
let gctx = ctx.module.to_ctx();
|
||||
return Err(Error::InitializationTypeMismatch {
|
||||
name: o.name.span,
|
||||
expected: explicit_ty.to_wgsl(&gctx),
|
||||
got: inferred_type.to_wgsl(&gctx),
|
||||
expected: explicit_ty.to_wgsl(&gctx).into(),
|
||||
got: inferred_type.to_wgsl(&gctx).into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1271,8 +1261,8 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
let gctx = &ctx.module.to_ctx();
|
||||
return Err(Error::InitializationTypeMismatch {
|
||||
name: l.name.span,
|
||||
expected: ty.to_wgsl(gctx),
|
||||
got: init_ty.to_wgsl(gctx),
|
||||
expected: ty.to_wgsl(gctx).into(),
|
||||
got: init_ty.to_wgsl(gctx).into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1302,15 +1292,10 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
let init = ectx
|
||||
.try_automatic_conversions(init, &ty_res, v.name.span)
|
||||
.map_err(|error| match error {
|
||||
Error::AutoConversion {
|
||||
dest_span: _,
|
||||
dest_type,
|
||||
source_span: _,
|
||||
source_type,
|
||||
} => Error::InitializationTypeMismatch {
|
||||
Error::AutoConversion(e) => Error::InitializationTypeMismatch {
|
||||
name: v.name.span,
|
||||
expected: dest_type,
|
||||
got: source_type,
|
||||
expected: e.dest_type,
|
||||
got: e.source_type,
|
||||
},
|
||||
other => other,
|
||||
})?;
|
||||
@ -1854,9 +1839,9 @@ 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),
|
||||
from_type: ty.to_wgsl(gctx).into(),
|
||||
span: ty_span,
|
||||
to_type: to_resolved.to_wgsl(gctx),
|
||||
to_type: to_resolved.to_wgsl(gctx).into(),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user