pub use super::depth::{DEFAULT_MAX_CALL_DEPTH, DEFAULT_MAX_NESTING_DEPTH, DEFAULT_MAX_NODE_COUNT};
use crate::ir_inner::model::expr::Ident;
use crate::ir_inner::model::types::DataType;
use crate::validate::{err, ValidationError};
use rustc_hash::FxHashSet;
#[derive(Debug, Clone)]
pub(crate) struct Binding {
pub(crate) ty: DataType,
pub(crate) mutable: bool,
pub(crate) uniform: bool,
}
#[inline]
pub(crate) fn check_sibling_duplicate(
name: &Ident,
region_bindings: &mut FxHashSet<Ident>,
allow_duplicate_siblings: bool,
errors: &mut Vec<ValidationError>,
) -> bool {
if region_bindings.insert(name.clone()) {
return false;
}
if allow_duplicate_siblings {
return false;
}
errors.push(err(format!(
"V032: duplicate sibling let binding `{name}` in the same region. Fix: rename one binding or move one declaration into an inner Block/Region/Loop if a new scope is intended."
)));
true
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn first_binding_is_not_duplicate() {
let mut region_bindings = FxHashSet::default();
let mut errors = Vec::new();
let dup =
check_sibling_duplicate(&Ident::from("x"), &mut region_bindings, false, &mut errors);
assert!(!dup);
assert!(errors.is_empty());
}
#[test]
fn second_binding_is_duplicate() {
let mut region_bindings = FxHashSet::default();
let mut errors = Vec::new();
check_sibling_duplicate(&Ident::from("x"), &mut region_bindings, false, &mut errors);
let dup =
check_sibling_duplicate(&Ident::from("x"), &mut region_bindings, false, &mut errors);
assert!(dup);
assert_eq!(errors.len(), 1);
assert!(errors[0].message().contains("V032"));
}
#[test]
fn different_names_not_duplicate() {
let mut region_bindings = FxHashSet::default();
let mut errors = Vec::new();
check_sibling_duplicate(&Ident::from("x"), &mut region_bindings, false, &mut errors);
let dup =
check_sibling_duplicate(&Ident::from("y"), &mut region_bindings, false, &mut errors);
assert!(!dup);
assert!(errors.is_empty());
}
#[test]
fn duplicate_sibling_allowed_by_explicit_shadowing_mode() {
let mut region_bindings = FxHashSet::default();
let mut errors = Vec::new();
check_sibling_duplicate(&Ident::from("x"), &mut region_bindings, true, &mut errors);
let dup =
check_sibling_duplicate(&Ident::from("x"), &mut region_bindings, true, &mut errors);
assert!(!dup);
assert!(errors.is_empty());
}
}