From b61b100fa3791799d6664e1079ef66beb9c83df6 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Mon, 2 Nov 2020 19:34:37 -0500 Subject: [PATCH] [ir] LocalVariableError --- src/proc/validator.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/proc/validator.rs b/src/proc/validator.rs index de37ec5769..27576433a2 100644 --- a/src/proc/validator.rs +++ b/src/proc/validator.rs @@ -32,12 +32,26 @@ pub enum GlobalVariableError { OutOfRangeBinding, } +#[derive(Clone, Debug, thiserror::Error)] +pub enum LocalVariableError { + #[error("Initializer is not a constant expression")] + InitializerConst, + #[error("Initializer doesn't match the variable type")] + InitializerType, +} + #[derive(Clone, Debug, thiserror::Error)] pub enum FunctionError { #[error(transparent)] Resolve(#[from] ResolveError), #[error("There are instructions after `return`/`break`/`continue`")] InvalidControlFlowExitTail, + #[error("Local variable {handle:?} '{name}' is invalid: {error:?}")] + LocalVariable { + handle: Handle, + name: String, + error: LocalVariableError, + }, } #[derive(Clone, Debug, thiserror::Error)] @@ -209,6 +223,21 @@ impl Validator { Ok(()) } + fn validate_local_var( + &self, + var: &crate::LocalVariable, + _fun: &crate::Function, + _types: &Arena, + ) -> Result<(), LocalVariableError> { + log::debug!("var {:?}", var); + if let Some(_expr_handle) = var.init { + if false { + return Err(LocalVariableError::InitializerConst); + } + } + Ok(()) + } + fn validate_function( &mut self, fun: &crate::Function, @@ -223,6 +252,15 @@ impl Validator { }; self.typifier .resolve_all(&fun.expressions, &module.types, &resolve_ctx)?; + + for (var_handle, var) in fun.local_variables.iter() { + self.validate_local_var(var, fun, &module.types) + .map_err(|error| FunctionError::LocalVariable { + handle: var_handle, + name: var.name.clone().unwrap_or_default(), + error, + })?; + } Ok(()) }