Prevent matching on a reference once and for all

This commit is contained in:
Dzmitry Malyshau
2021-03-12 11:27:44 -05:00
committed by Dzmitry Malyshau
parent dd273e254a
commit 9e5cc4c9e4
9 changed files with 132 additions and 126 deletions

View File

@@ -85,7 +85,7 @@ pub enum Version {
impl Version { impl Version {
/// Returns true if self is `Version::Embedded` (i.e. is a es version) /// Returns true if self is `Version::Embedded` (i.e. is a es version)
fn is_es(&self) -> bool { fn is_es(&self) -> bool {
match self { match *self {
Version::Desktop(_) => false, Version::Desktop(_) => false,
Version::Embedded(_) => true, Version::Embedded(_) => true,
} }
@@ -98,9 +98,9 @@ impl Version {
/// As an invalid version number will never be added to the supported version list /// As an invalid version number will never be added to the supported version list
/// so this also checks for version validity /// so this also checks for version validity
fn is_supported(&self) -> bool { fn is_supported(&self) -> bool {
match self { match *self {
Version::Desktop(v) => SUPPORTED_CORE_VERSIONS.contains(v), Version::Desktop(v) => SUPPORTED_CORE_VERSIONS.contains(&v),
Version::Embedded(v) => SUPPORTED_ES_VERSIONS.contains(v), Version::Embedded(v) => SUPPORTED_ES_VERSIONS.contains(&v),
} }
} }
} }
@@ -117,7 +117,7 @@ impl PartialOrd for Version {
impl fmt::Display for Version { impl fmt::Display for Version {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match *self {
Version::Desktop(v) => write!(f, "{} core", v), Version::Desktop(v) => write!(f, "{} core", v),
Version::Embedded(v) => write!(f, "{} es", v), Version::Embedded(v) => write!(f, "{} es", v),
} }
@@ -1615,7 +1615,7 @@ impl<'a, W: Write> Writer<'a, W> {
Expression::Binary { op, left, right } => { Expression::Binary { op, left, right } => {
// Holds `Some(function_name)` if the binary operation is // Holds `Some(function_name)` if the binary operation is
// implemented as a function call // implemented as a function call
let function = if let (TypeInner::Vector { .. }, TypeInner::Vector { .. }) = ( let function = if let (&TypeInner::Vector { .. }, &TypeInner::Vector { .. }) = (
ctx.typifier.get(left, &self.module.types), ctx.typifier.get(left, &self.module.types),
ctx.typifier.get(right, &self.module.types), ctx.typifier.get(right, &self.module.types),
) { ) {

View File

@@ -993,7 +993,7 @@ impl<W: Write> Writer<W> {
let (_, global) = module let (_, global) = module
.global_variables .global_variables
.iter() .iter()
.find(|(_, var)| var.ty == handle) .find(|&(_, ref var)| var.ty == handle)
.expect("Unable to find a global variable using the image type"); .expect("Unable to find a global variable using the image type");
let access = if global let access = if global
.storage_access .storage_access

View File

@@ -71,12 +71,12 @@ impl<'a> Program<'a> {
left: &ExpressionRule, left: &ExpressionRule,
right: &ExpressionRule, right: &ExpressionRule,
) -> Result<ExpressionRule, ErrorKind> { ) -> Result<ExpressionRule, ErrorKind> {
let left_is_vector = match self.resolve_type(left.expression)? { let left_is_vector = match *self.resolve_type(left.expression)? {
crate::TypeInner::Vector { .. } => true, crate::TypeInner::Vector { .. } => true,
_ => false, _ => false,
}; };
let right_is_vector = match self.resolve_type(right.expression)? { let right_is_vector = match *self.resolve_type(right.expression)? {
crate::TypeInner::Vector { .. } => true, crate::TypeInner::Vector { .. } => true,
_ => false, _ => false,
}; };

View File

@@ -189,13 +189,11 @@ impl<'a> ConstantSolver<'a> {
match inner { match inner {
ConstantInner::Scalar { ref mut value, .. } => { ConstantInner::Scalar { ref mut value, .. } => {
let initial = value.clone();
*value = match kind { *value = match kind {
ScalarKind::Sint => ScalarValue::Sint(inner_cast(initial)), ScalarKind::Sint => ScalarValue::Sint(inner_cast(*value)),
ScalarKind::Uint => ScalarValue::Uint(inner_cast(initial)), ScalarKind::Uint => ScalarValue::Uint(inner_cast(*value)),
ScalarKind::Float => ScalarValue::Float(inner_cast(initial)), ScalarKind::Float => ScalarValue::Float(inner_cast(*value)),
ScalarKind::Bool => ScalarValue::Bool(inner_cast::<u64>(initial) != 0), ScalarKind::Bool => ScalarValue::Bool(inner_cast::<u64>(*value) != 0),
} }
} }
ConstantInner::Composite { ConstantInner::Composite {
@@ -229,15 +227,15 @@ impl<'a> ConstantSolver<'a> {
match inner { match inner {
ConstantInner::Scalar { ref mut value, .. } => match op { ConstantInner::Scalar { ref mut value, .. } => match op {
UnaryOperator::Negate => match value { UnaryOperator::Negate => match *value {
ScalarValue::Sint(v) => *v = -*v, ScalarValue::Sint(ref mut v) => *v = -*v,
ScalarValue::Float(v) => *v = -*v, ScalarValue::Float(ref mut v) => *v = -*v,
_ => return Err(ConstantSolvingError::InvalidUnaryOpArg), _ => return Err(ConstantSolvingError::InvalidUnaryOpArg),
}, },
UnaryOperator::Not => match value { UnaryOperator::Not => match *value {
ScalarValue::Sint(v) => *v = !*v, ScalarValue::Sint(ref mut v) => *v = !*v,
ScalarValue::Uint(v) => *v = !*v, ScalarValue::Uint(ref mut v) => *v = !*v,
ScalarValue::Bool(v) => *v = !*v, ScalarValue::Bool(ref mut v) => *v = !*v,
_ => return Err(ConstantSolvingError::InvalidUnaryOpArg), _ => return Err(ConstantSolvingError::InvalidUnaryOpArg),
}, },
}, },
@@ -274,12 +272,13 @@ impl<'a> ConstantSolver<'a> {
let inner = match (left, right) { let inner = match (left, right) {
( (
ConstantInner::Scalar { &ConstantInner::Scalar {
value: left_value, value: left_value,
width, width,
}, },
ConstantInner::Scalar { &ConstantInner::Scalar {
value: right_value, .. value: right_value,
width: _,
}, },
) => { ) => {
let value = match op { let value = match op {
@@ -333,8 +332,8 @@ impl<'a> ConstantSolver<'a> {
} }
(ScalarValue::Bool(a), ScalarValue::Bool(b)) => { (ScalarValue::Bool(a), ScalarValue::Bool(b)) => {
ScalarValue::Bool(match op { ScalarValue::Bool(match op {
BinaryOperator::LogicalAnd => *a && *b, BinaryOperator::LogicalAnd => a && b,
BinaryOperator::LogicalOr => *a || *b, BinaryOperator::LogicalOr => a || b,
_ => return Err(ConstantSolvingError::InvalidBinaryOpArgs), _ => return Err(ConstantSolvingError::InvalidBinaryOpArgs),
}) })
} }
@@ -342,10 +341,7 @@ impl<'a> ConstantSolver<'a> {
}, },
}; };
ConstantInner::Scalar { ConstantInner::Scalar { value, width }
value,
width: *width,
}
} }
_ => return Err(ConstantSolvingError::InvalidBinaryOpArgs), _ => return Err(ConstantSolvingError::InvalidBinaryOpArgs),
}; };

View File

@@ -26,32 +26,34 @@ pub enum ErrorKind {
impl fmt::Display for ErrorKind { impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match *self {
ErrorKind::EndOfFile => write!(f, "Unexpected end of file"), ErrorKind::EndOfFile => write!(f, "Unexpected end of file"),
ErrorKind::InvalidInput => write!(f, "InvalidInput"), ErrorKind::InvalidInput => write!(f, "InvalidInput"),
ErrorKind::InvalidProfile(meta, val) => { ErrorKind::InvalidProfile(ref meta, ref val) => {
write!(f, "Invalid profile {} at {:?}", val, meta) write!(f, "Invalid profile {} at {:?}", val, meta)
} }
ErrorKind::InvalidToken(token) => write!(f, "Invalid Token {:?}", token), ErrorKind::InvalidToken(ref token) => write!(f, "Invalid Token {:?}", token),
ErrorKind::InvalidVersion(meta, val) => { ErrorKind::InvalidVersion(ref meta, ref val) => {
write!(f, "Invalid version {} at {:?}", val, meta) write!(f, "Invalid version {} at {:?}", val, meta)
} }
ErrorKind::IoError(error) => write!(f, "IO Error {}", error), ErrorKind::IoError(ref error) => write!(f, "IO Error {}", error),
ErrorKind::ParserFail => write!(f, "Parser failed"), ErrorKind::ParserFail => write!(f, "Parser failed"),
ErrorKind::ParserStackOverflow => write!(f, "Parser stack overflow"), ErrorKind::ParserStackOverflow => write!(f, "Parser stack overflow"),
ErrorKind::NotImplemented(msg) => write!(f, "Not implemented: {}", msg), ErrorKind::NotImplemented(ref msg) => write!(f, "Not implemented: {}", msg),
ErrorKind::UnknownVariable(meta, val) => { ErrorKind::UnknownVariable(ref meta, ref val) => {
write!(f, "Unknown variable {} at {:?}", val, meta) write!(f, "Unknown variable {} at {:?}", val, meta)
} }
ErrorKind::UnknownField(meta, val) => write!(f, "Unknown field {} at {:?}", val, meta), ErrorKind::UnknownField(ref meta, ref val) => {
write!(f, "Unknown field {} at {:?}", val, meta)
}
#[cfg(feature = "glsl-validate")] #[cfg(feature = "glsl-validate")]
ErrorKind::VariableAlreadyDeclared(val) => { ErrorKind::VariableAlreadyDeclared(ref val) => {
write!(f, "Variable {} already declared in current scope", val) write!(f, "Variable {} already declared in current scope", val)
} }
ErrorKind::ExpectedConstant => write!(f, "Expected constant"), ErrorKind::ExpectedConstant => write!(f, "Expected constant"),
ErrorKind::SemanticError(msg) => write!(f, "Semantic error: {}", msg), ErrorKind::SemanticError(ref msg) => write!(f, "Semantic error: {}", msg),
ErrorKind::PreprocessorError(val) => write!(f, "Preprocessor error: {}", val), ErrorKind::PreprocessorError(ref val) => write!(f, "Preprocessor error: {}", val),
ErrorKind::WrongNumberArgs(fun, expected, actual) => { ErrorKind::WrongNumberArgs(ref fun, expected, actual) => {
write!(f, "{} requires {} args, got {}", fun, expected, actual) write!(f, "{} requires {} args, got {}", fun, expected, actual)
} }
} }

View File

@@ -328,7 +328,7 @@ pomelo! {
extra.unary_expr(UnaryOperator::Negate, &tgt) extra.unary_expr(UnaryOperator::Negate, &tgt)
} }
unary_expression ::= Bang unary_expression(tgt) { unary_expression ::= Bang unary_expression(tgt) {
if let TypeInner::Scalar { kind: ScalarKind::Bool, .. } = extra.resolve_type(tgt.expression)? { if let TypeInner::Scalar { kind: ScalarKind::Bool, .. } = *extra.resolve_type(tgt.expression)? {
extra.unary_expr(UnaryOperator::Not, &tgt) extra.unary_expr(UnaryOperator::Not, &tgt)
} else { } else {
return Err(ErrorKind::SemanticError("Cannot apply '!' to non bool type".into())) return Err(ErrorKind::SemanticError("Cannot apply '!' to non bool type".into()))
@@ -1070,18 +1070,18 @@ pomelo! {
if let Some(d) = d { if let Some(d) = d {
// TODO: handle multiple storage qualifiers // TODO: handle multiple storage qualifiers
let storage = d.type_qualifiers.iter().find_map(|tq| { let storage = d.type_qualifiers.iter().find_map(|tq| {
if let TypeQualifier::StorageQualifier(sc) = tq { Some(*sc) } else { None } if let TypeQualifier::StorageQualifier(sc) = *tq { Some(sc) } else { None }
}).unwrap_or(StorageQualifier::StorageClass(StorageClass::Private)); }).unwrap_or(StorageQualifier::StorageClass(StorageClass::Private));
match storage { match storage {
StorageQualifier::StorageClass(storage_class) => { StorageQualifier::StorageClass(storage_class) => {
// TODO: Check that the storage qualifiers allow for the bindings // TODO: Check that the storage qualifiers allow for the bindings
let binding = d.type_qualifiers.iter().find_map(|tq| { let binding = d.type_qualifiers.iter().find_map(|tq| {
if let TypeQualifier::Binding(b) = tq { Some(b.clone()) } else { None } if let TypeQualifier::Binding(ref b) = *tq { Some(b.clone()) } else { None }
}); });
let interpolation = d.type_qualifiers.iter().find_map(|tq| { let interpolation = d.type_qualifiers.iter().find_map(|tq| {
if let TypeQualifier::Interpolation(i) = tq { Some(*i) } else { None } if let TypeQualifier::Interpolation(interp) = *tq { Some(interp) } else { None }
}); });
for (id, initializer) in d.ids_initializers { for (id, initializer) in d.ids_initializers {

View File

@@ -126,7 +126,7 @@ impl FlowGraph {
ControlFlowEdgeType::Forward, ControlFlowEdgeType::Forward,
); );
for (_, target_block_id) in targets.iter() { for &(_, target_block_id) in targets.iter() {
let target_node_index = block_to_node[&target_block_id]; let target_node_index = block_to_node[&target_block_id];
self.flow.add_edge( self.flow.add_edge(
@@ -201,7 +201,7 @@ impl FlowGraph {
let phis = std::mem::replace(&mut self.flow[node_index].phis, Vec::new()); let phis = std::mem::replace(&mut self.flow[node_index].phis, Vec::new());
for phi in phis.iter() { for phi in phis.iter() {
let phi_var = &lookup_expression[&phi.id]; let phi_var = &lookup_expression[&phi.id];
for (variable_id, parent_id) in phi.variables.iter() { for &(variable_id, parent_id) in phi.variables.iter() {
let variable = &lookup_expression[&variable_id]; let variable = &lookup_expression[&variable_id];
let parent_node = &mut self.flow[self.block_to_node[&parent_id]]; let parent_node = &mut self.flow[self.block_to_node[&parent_id]];

View File

@@ -55,65 +55,6 @@ pub enum Token<'a> {
End, End,
} }
impl<'a> Error<'a> {
fn as_parse_error(&self, source: &'a str) -> ParseError<'a> {
match self {
Error::Unexpected((_, unexpected_span), expected) => ParseError {
message: format!(
"expected {}, found '{}'",
expected,
&source[unexpected_span.clone()],
),
labels: vec![(unexpected_span.clone(), format!("expected {}", expected))],
notes: vec![],
source,
},
Error::BadInteger(bad_span) => ParseError {
message: format!(
"expected integer literal, found `{}`",
&source[bad_span.clone()],
),
labels: vec![(bad_span.clone(), "expected integer".to_string())],
notes: vec![],
source,
},
Error::BadFloat(bad_span) => ParseError {
message: format!(
"expected floating-point literal, found `{}`",
&source[bad_span.clone()],
),
labels: vec![(
bad_span.clone(),
"expected floating-point literal".to_string(),
)],
notes: vec![],
source,
},
Error::BadScalarWidth(bad_span, width) => ParseError {
message: format!("invalid width of `{}` for literal", width,),
labels: vec![(bad_span.clone(), "invalid width".to_string())],
notes: vec!["valid width is 32".to_string()],
source,
},
Error::BadAccessor(accessor_span) => ParseError {
message: format!(
"invalid field accessor `{}`",
&source[accessor_span.clone()],
),
labels: vec![(accessor_span.clone(), "invalid accessor".to_string())],
notes: vec![],
source,
},
error => ParseError {
message: error.to_string(),
labels: vec![],
notes: vec![],
source,
},
}
}
}
#[derive(Clone, Debug, Error)] #[derive(Clone, Debug, Error)]
pub enum Error<'a> { pub enum Error<'a> {
#[error("")] #[error("")]
@@ -176,6 +117,65 @@ pub enum Error<'a> {
Other, Other,
} }
impl<'a> Error<'a> {
fn as_parse_error(&self, source: &'a str) -> ParseError<'a> {
match *self {
Error::Unexpected((_, ref unexpected_span), expected) => ParseError {
message: format!(
"expected {}, found '{}'",
expected,
&source[unexpected_span.clone()],
),
labels: vec![(unexpected_span.clone(), format!("expected {}", expected))],
notes: vec![],
source,
},
Error::BadInteger(ref bad_span) => ParseError {
message: format!(
"expected integer literal, found `{}`",
&source[bad_span.clone()],
),
labels: vec![(bad_span.clone(), "expected integer".to_string())],
notes: vec![],
source,
},
Error::BadFloat(ref bad_span) => ParseError {
message: format!(
"expected floating-point literal, found `{}`",
&source[bad_span.clone()],
),
labels: vec![(
bad_span.clone(),
"expected floating-point literal".to_string(),
)],
notes: vec![],
source,
},
Error::BadScalarWidth(ref bad_span, width) => ParseError {
message: format!("invalid width of `{}` for literal", width,),
labels: vec![(bad_span.clone(), "invalid width".to_string())],
notes: vec!["valid width is 32".to_string()],
source,
},
Error::BadAccessor(ref accessor_span) => ParseError {
message: format!(
"invalid field accessor `{}`",
&source[accessor_span.clone()],
),
labels: vec![(accessor_span.clone(), "invalid accessor".to_string())],
notes: vec![],
source,
},
ref error => ParseError {
message: error.to_string(),
labels: vec![],
notes: vec![],
source,
},
}
}
}
trait StringValueLookup<'a> { trait StringValueLookup<'a> {
type Value; type Value;
fn lookup(&self, key: &'a str) -> Result<Self::Value, Error<'a>>; fn lookup(&self, key: &'a str) -> Result<Self::Value, Error<'a>>;
@@ -553,7 +553,7 @@ impl Parser {
name: &'a str, name: &'a str,
mut ctx: ExpressionContext<'a, '_, '_>, mut ctx: ExpressionContext<'a, '_, '_>,
) -> Result<Option<LocalFunctionCall>, Error<'a>> { ) -> Result<Option<LocalFunctionCall>, Error<'a>> {
let fun_handle = match ctx.functions.iter().find(|(_, fun)| match fun.name { let fun_handle = match ctx.functions.iter().find(|&(_, fun)| match fun.name {
Some(ref string) => string == name, Some(ref string) => string == name,
None => false, None => false,
}) { }) {
@@ -1033,15 +1033,22 @@ impl Parser {
let expr = if components.is_empty() { let expr = if components.is_empty() {
let last_component_inner = ctx.resolve_type(last_component)?; let last_component_inner = ctx.resolve_type(last_component)?;
match (&inner, last_component_inner) { match (&inner, last_component_inner) {
(crate::TypeInner::Scalar { .. }, crate::TypeInner::Scalar { .. }) (
| (crate::TypeInner::Matrix { .. }, crate::TypeInner::Matrix { .. }) &crate::TypeInner::Scalar { .. },
| (crate::TypeInner::Vector { .. }, crate::TypeInner::Vector { .. }) => { &crate::TypeInner::Scalar { .. },
crate::Expression::As { )
expr: last_component, | (
kind: kind.ok_or(Error::BadTypeCast(word))?, &crate::TypeInner::Matrix { .. },
convert: true, &crate::TypeInner::Matrix { .. },
} )
} | (
&crate::TypeInner::Vector { .. },
&crate::TypeInner::Vector { .. },
) => crate::Expression::As {
expr: last_component,
kind: kind.ok_or(Error::BadTypeCast(word))?,
convert: true,
},
_ => { _ => {
return Err(Error::BadTypeCast(word)); return Err(Error::BadTypeCast(word));
} }

View File

@@ -20,12 +20,6 @@ emitted in order to take effect. This happens in one of the following ways:
!*/ !*/
#![warn(
trivial_casts,
trivial_numeric_casts,
unused_extern_crates,
unused_qualifications
)]
#![allow( #![allow(
clippy::new_without_default, clippy::new_without_default,
clippy::unneeded_field_pattern, clippy::unneeded_field_pattern,
@@ -33,6 +27,13 @@ emitted in order to take effect. This happens in one of the following ways:
)] )]
// TODO: use `strip_prefix` instead when Rust 1.45 <= MSRV // TODO: use `strip_prefix` instead when Rust 1.45 <= MSRV
#![allow(clippy::manual_strip, clippy::unknown_clippy_lints)] #![allow(clippy::manual_strip, clippy::unknown_clippy_lints)]
#![warn(
trivial_casts,
trivial_numeric_casts,
unused_extern_crates,
unused_qualifications,
clippy::pattern_type_mismatch
)]
#![deny(clippy::panic)] #![deny(clippy::panic)]
mod arena; mod arena;
@@ -418,7 +419,7 @@ pub struct Constant {
} }
/// A literal scalar value, used in constants. /// A literal scalar value, used in constants.
#[derive(Debug, PartialEq, Clone, PartialOrd)] #[derive(Debug, PartialEq, Clone, Copy, PartialOrd)]
#[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))] #[cfg_attr(feature = "deserialize", derive(Deserialize))]
pub enum ScalarValue { pub enum ScalarValue {
@@ -429,7 +430,7 @@ pub enum ScalarValue {
} }
/// Additional information, dependent on the kind of constant. /// Additional information, dependent on the kind of constant.
#[derive(Debug, PartialEq, Clone)] #[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))] #[cfg_attr(feature = "deserialize", derive(Deserialize))]
pub enum ConstantInner { pub enum ConstantInner {