charon_lib/transform/
unbind_item_vars.rs1use derive_generic_visitor::*;
4use index_vec::Idx;
5
6use crate::ast::*;
7
8use super::{TransformCtx, ctx::TransformPass};
9
10#[derive(Default, Visitor)]
12pub(crate) struct UnbindVarVisitor {
13 binder_depth: DeBruijnId,
15}
16
17impl VisitorWithBinderDepth for UnbindVarVisitor {
18 fn binder_depth_mut(&mut self) -> &mut DeBruijnId {
19 &mut self.binder_depth
20 }
21}
22impl VisitAstMut for UnbindVarVisitor {
23 fn visit<'a, T: AstVisitable>(&'a mut self, x: &mut T) -> ControlFlow<Self::Break> {
24 VisitWithBinderDepth::new(self).visit(x)
25 }
26
27 fn exit_de_bruijn_var<T: AstVisitable + Idx>(&mut self, var: &mut DeBruijnVar<T>) {
28 match var {
29 DeBruijnVar::Bound(dbid, varid) if *dbid == self.binder_depth => {
30 *var = DeBruijnVar::Free(*varid)
31 }
32 DeBruijnVar::Bound(..) => {}
33 DeBruijnVar::Free(_) => unreachable!("Found unexpected free variable"),
34 }
35 }
36}
37
38pub struct Check;
39impl TransformPass for Check {
40 fn transform_ctx(&self, ctx: &mut TransformCtx) {
41 let mut visitor = UnbindVarVisitor::default();
42 for mut item in ctx.translated.all_items_mut() {
43 let _ = item.drive_mut(&mut visitor);
44 }
45 }
46}