knave 0.12.11

A Lisp programming language for humans and agents that infers types and ownership and compiles to readable Rust
Documentation
use rustc_hash::FxHashMap;

use crate::core::{BindingId, TraitMethod, TypeExpr, TypeExprKind};
use crate::source::Span;

#[derive(Clone, Copy)]
pub(super) struct SelflessMethod {
    pub trait_binding: BindingId,
    pub signature: Span,
}

#[derive(Default)]
pub(super) struct SelflessMethods {
    methods: FxHashMap<BindingId, SelflessMethod>,
}

impl SelflessMethods {
    pub fn record(
        &mut self,
        method: &TraitMethod,
        trait_binding: BindingId,
        self_variable: BindingId,
    ) {
        if !Self::mentions(&method.signature, self_variable) {
            let signature = method.signature.span();
            let selfless = SelflessMethod {
                trait_binding,
                signature,
            };
            self.methods.insert(method.binding, selfless);
        }
    }

    pub fn get(&self, method: BindingId) -> Option<SelflessMethod> {
        self.methods.get(&method).copied()
    }

    fn mentions(signature: &TypeExpr, variable: BindingId) -> bool {
        match signature.kind() {
            TypeExprKind::Named(binding, _) if *binding == variable => true,
            TypeExprKind::Where(_, inner) => Self::mentions(inner, variable),
            TypeExprKind::With(outer, inner) => {
                Self::mentions(outer, variable) || Self::mentions(inner, variable)
            }
            _ => signature
                .parts()
                .into_iter()
                .any(|part| Self::mentions(part, variable)),
        }
    }
}