Borrow Owned Value From Cached Struct

I use a 3rd party library to parse a file. The parser creates a struct ParsedSource. ParsedSource represents a tree of data. I have a struct SchemyNode that wraps nodes found in ParsedSource, so that I can quickly reference them and retain metadata about them. I have a lifetime issue. SchemyNode holds references to nodes found in ParsedSource. This seems to work fine except in the very beginning when I try to pass the first child of ParsedSource, Module, to the first SchemyNode. What do I do?

Link to source file

Diagnostic Error

error[E0515]: cannot return value referencing local variable `borrow`
  --> src/typescript/module_cache.rs:39:9
   |
38 |         let source = borrow.get(path).unwrap();
   |                      ---------------- `borrow` is borrowed here
39 |         SchemyNode::from_module(source.module(), &self.context.clone())
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function

I don't want to clone module, but I think I have to.

Why not &self.context?

All SchemyNodes need a mutable reference to context.

Well, then &mut self.context.


By the way, it looks like the module is a problem, too. The borrow guard returned by RefCell can't hand out references to the wrapped value directly, because then the very point of the RefCell would be moot (it couldn't track borrows at runtime, causing unsoundness). Any reference you get from a RefCell, mutable or immutable, will necessarily be tied to the scope of the guard object (Ref or RefMut).

Yes, that's the problem. Are you able to see the intent?

Yes, but I'm afraid what you want is impossible (or at least not usefully possible). You can't have such borrows, as they fundamentally violate memory safety.

You could store the guard object directly in some returned wrapper similar to RefMut::map, and then get short-lived references out of it and construct nodes with them only locally. But that's not a solution, either, because as soon as you create the second such node, the RefCell::borrow_mut() call will panic.

crud, i think i need to learn some new tricks. I'm using the context to keep a reference to all nodes, so that I have quick access to them in the future. I'm trying to hide the context from the rest of the program, so that I can work exclusively with nodes.

That generally doesn't work out well. You should use some sort of node ID instead.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.