fn intern_expression(
        &mut self,
        relation: &mut MirRelationExpr,
    ) -> Result<(), crate::TransformError> {
        self.checked_recur_mut(|this| {
            match relation {
                MirRelationExpr::Let { id, value, body } => {
                    this.intern_expression(value)?;
                    let new_id = if let MirRelationExpr::Get {
                        id: Id::Local(x), ..
                    } = **value
                    {
                        x
                    } else {
                        panic!("Invariant violated")
                    };
                    this.rebindings.insert(*id, new_id);
                    this.intern_expression(body)?;
                    let body = body.take_dangerous();
                    this.rebindings.remove(id);
                    *relation = body;
                }
                MirRelationExpr::Get { id, .. } => {
                    if let Id::Local(id) = id {
                        *id = this.rebindings[id];
                    }
                }

                _ => {
                    // All other expressions just need to apply the logic recursively.
                    relation.try_visit_mut_children(&mut |expr| this.intern_expression(expr))?;
                }
            };

            // This should be fast, as it depends directly on only `Get` expressions.
            let typ = relation.typ();
            // We want to maintain the invariant that `relation` ends up as a local `Get`.
            if let MirRelationExpr::Get {
                id: Id::Local(_), ..
            } = relation
            {
                // Do nothing, as the expression is already a local `Get` expression.
            } else {
                // Either find an instance of `relation` or insert this one.
                let bindings_len = this.bindings.len() as u64;
                let id = this
                    .bindings
                    .entry(relation.take_dangerous())
                    .or_insert(bindings_len);
                *relation = MirRelationExpr::Get {
                    id: Id::Local(LocalId::new(*id)),
                    typ,
                }
            }

            Ok(())
        })
    }
/// Replace `relation` with an equivalent `Get` expression referencing a location in `bindings`.
///
/// The algorithm performs a post-order traversal of the expression tree, binding each distinct
/// expression to a new local identifier. It maintains the invariant that `bindings` contains no
/// `Let` expressions, nor any two structurally equivalent expressions.
///
/// Once each sub-expression is replaced by a canonical `Get` expression, each expression is also
/// in a canonical representation, which is used to check for prior instances and drives re-use.


Once each sub-expression is replaced by a canonical `Get` expression, each expression is also
in a canonical representation, which is used to check for prior instances and drives re-use.
Once each sub - expression is replaced by a canonical ` Get ` expression each expression is also in a canonical representation which is used to check for prior instances and drives re - use .
fn intern_expression(
        &mut self,
        relation: &mut MirRelationExpr,
    ) -> Result<(), crate::TransformError> {
        self.checked_recur_mut(|this| {
            match relation {
                MirRelationExpr::Let { id, value, body } => {
                    this.intern_expression(value)?;
                    let new_id = if let MirRelationExpr::Get {
                        id: Id::Local(x), ..
                    } = **value
                    {
                        x
                    } else {
                        panic!("Invariant violated")
                    };
                    this.rebindings.insert(*id, new_id);
                    this.intern_expression(body)?;
                    let body = body.take_dangerous();
                    this.rebindings.remove(id);
                    *relation = body;
                }
                MirRelationExpr::Get { id, .. } => {
                    if let Id::Local(id) = id {
                        *id = this.rebindings[id];
                    }
                }
                _ => {
                    // All other expressions just need to apply the logic recursively.
                    relation.try_visit_mut_children(&mut |expr| this.intern_expression(expr))?;
                }
            };
            // This should be fast, as it depends directly on only `Get` expressions.
            let typ = relation.typ();
            // We want to maintain the invariant that `relation` ends up as a local `Get`.
            if let MirRelationExpr::Get {
                id: Id::Local(_), ..
            } = relation
            {
                // Do nothing, as the expression is already a local `Get` expression.
            } else {
                // Either find an instance of `relation` or insert this one.
                let bindings_len = this.bindings.len() as u64;
                let id = this
                    .bindings
                    .entry(relation.take_dangerous())
                    .or_insert(bindings_len);
                *relation = MirRelationExpr::Get {
                    id: Id::Local(LocalId::new(*id)),
                    typ,
                }
            }
            Ok(())
        })
    }
fn intern_expression ( & mut self , relation : & mut MirRelationExpr , ) -> Result < ( ) , crate :: TransformError > { self . checked_recur_mut ( | this | { match relation { MirRelationExpr :: Let { id , value , body } => { this . intern_expression ( value ) ? ; let new_id = if let MirRelationExpr :: Get { id : Id :: Local ( x ) , .. } = * * value { x } else { panic ! ( " " ) } ; this . rebindings . insert ( * id , new_id ) ; this . intern_expression ( body ) ? ; let body = body . take_dangerous ( ) ; this . rebindings . remove ( id ) ; * relation = body ; } MirRelationExpr :: Get { id , .. } => { if let Id :: Local ( id ) = id { * id = this . rebindings [ id ] ; } } _ => { // All other expressions just need to apply the logic recursively. relation . try_visit_mut_children ( & mut | expr | this . intern_expression ( expr ) ) ? ; } } ; // This should be fast, as it depends directly on only `Get` expressions. let typ = relation . typ ( ) ; // We want to maintain the invariant that `relation` ends up as a local `Get`. if let MirRelationExpr :: Get { id : Id :: Local ( _ ) , .. } = relation { // Do nothing, as the expression is already a local `Get` expression. } else { // Either find an instance of `relation` or insert this one. let bindings_len = this . bindings . len ( ) as u64 ; let id = this . bindings . entry ( relation . take_dangerous ( ) ) . or_insert ( bindings_len ) ; * relation = MirRelationExpr :: Get { id : Id :: Local ( LocalId :: new ( * id ) ) , typ , } } Ok ( ( ) ) } ) }
Replace `relation` with an equivalent `Get` expression referencing a location in `bindings`.
Replace ` relation ` with an equivalent ` Get ` expression referencing a location in ` bindings ` .
&mut self
relation
&mut MirRelationExpr
&mut self
relation
&mut MirRelationExpr