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