compose-idents 0.3.0

A Rust macro for generating new identifiers (names of variables, functions, traits, etc) by concatenating one or more arbitrary parts and applying other manipulations.
Documentation
use crate::ast::{Ast, Value, ValueKind};
use crate::core::{Environment, Type};
use crate::error::Error;
use crate::resolve::{Resolve, Scope};

impl Resolve for Value {
    /// Resolves a function call by resolving its arguments and binding the call to a built-in
    /// function.
    fn resolve(
        &self,
        _: &Environment,
        scope: &mut Scope,
        expected_type: Option<&Type>,
    ) -> Result<(), Error> {
        let mut metadata = scope.metadata_mut();
        let from_type = match self.kind() {
            ValueKind::Ident(ident) => match scope.get_name(ident.to_string().as_str()) {
                Some(value) => {
                    let id = value.id();
                    if let Some(metadata) = metadata.get_value_metadata(id) {
                        metadata.target_type.clone()
                    } else if let Some(metadata) = metadata.get_call_metadata(id) {
                        metadata.target_type.clone()
                    } else {
                        panic!(
                            "Expected metadata to be set for a value {} of a resolved alias {}",
                            id, ident
                        );
                    }
                }
                _ => self.type_(),
            },
            _ => self.type_(),
        };

        let expected_type = match expected_type {
            Some(expected_type) => expected_type,
            None => &from_type,
        };

        match Type::coercion_cost(&from_type, expected_type) {
            Some(coercion_cost) => {
                metadata.set_value_metadata(self.id(), expected_type.clone(), coercion_cost);
                Ok(())
            }
            None => Err(Error::make_coercion_error(&self.type_(), expected_type)),
        }
    }
}