pub trait Visit<Prim: PrimitiveType> {
    // Provided methods
    fn visit_type(&mut self, ty: &Type<Prim>) { ... }
    fn visit_var(&mut self, var: TypeVar) { ... }
    fn visit_primitive(&mut self, primitive: &Prim) { ... }
    fn visit_tuple(&mut self, tuple: &Tuple<Prim>) { ... }
    fn visit_object(&mut self, object: &Object<Prim>) { ... }
    fn visit_dyn_constraints(&mut self, constraints: &DynConstraints<Prim>) { ... }
    fn visit_function(&mut self, function: &Function<Prim>) { ... }
}
Expand description

Recursive traversal across the shared reference to a Type.

Inspired by the Visit trait from syn.

Examples

use arithmetic_typing::{
    ast::TypeAst, visit::{self, Visit},
    PrimitiveType, Slice, Tuple, UnknownLen, Type, TypeVar,
};

/// Counts the number of mentions of type / length params in a type.
#[derive(Default)]
pub struct Mentions {
    types: HashMap<usize, usize>,
    lengths: HashMap<usize, usize>,
}

impl<Prim: PrimitiveType> Visit<Prim> for Mentions {
    fn visit_var(&mut self, var: TypeVar) {
        *self.types.entry(var.index()).or_default() += 1;
    }

    fn visit_tuple(&mut self, tuple: &Tuple<Prim>) {
        let (_, middle, _) = tuple.parts();
        let len = middle.and_then(|middle| middle.len().components().0);
        if let Some(UnknownLen::Var(var)) = len {
            *self.lengths.entry(var.index()).or_default() += 1;
        }
        visit::visit_tuple(self, tuple);
    }
}

let ty = TypeAst::try_from("(...['T; N], ('T) -> 'U) -> [('T, 'U); N]")?;
let ty: Type = Type::try_from(&ty)?;

let mut mentions = Mentions::default();
mentions.visit_type(&ty);
assert_eq!(mentions.lengths[&0], 2); // `N` is mentioned twice
assert_eq!(mentions.types[&0], 3); // `T` is mentioned 3 times
assert_eq!(mentions.types[&1], 2); // `U` is mentioned twice

Provided Methods§

source

fn visit_type(&mut self, ty: &Type<Prim>)

Visits a generic type.

The default implementation calls one of more specific methods corresponding to the ty variant.

source

fn visit_var(&mut self, var: TypeVar)

Visits a type variable.

The default implementation does nothing.

source

fn visit_primitive(&mut self, primitive: &Prim)

Visits a primitive type.

The default implementation does nothing.

source

fn visit_tuple(&mut self, tuple: &Tuple<Prim>)

Visits a tuple type.

The default implementation calls Self::visit_type() for each tuple element, including the middle element if any.

source

fn visit_object(&mut self, object: &Object<Prim>)

Visits an object type.

source

fn visit_dyn_constraints(&mut self, constraints: &DynConstraints<Prim>)

Visits a Type::Dyn variant.

The default implementation visits the object constraint if it is present using Self::visit_object().

source

fn visit_function(&mut self, function: &Function<Prim>)

Visits a functional type.

The default implementation calls Self::visit_tuple() on arguments and then Self::visit_type() on the return value.

Implementors§