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