-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Removing RefCells and Cells from FunctionContext in trans #25332
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
r? @nrc (rust_highfive has picked a reviewer for you, use r? to override) |
If |
Since one of them is mutable, the pair would move every time, so we'd lose the function pointer unless we carefully threaded it back through every return value (I believe, anyway). We could work around that by constructing a fresh pair each time, but then you're really not gaining anything compared to just passing two parameters. I did consider trying it anyway though.
Yeah, like I commented in the other PR, I think that in this case it may have been better to just get rid of
Making everything a method on |
Well, your wish came true. A few months ago, actually :). As for creating a fresh pair every time, you could use a |
...Whoa, how did I miss that? Okay then, that makes the method solution a lot more attractive.
Doesn't reborrowing only occur if the function takes a reference in the first place (in which case you wouldn't be passing by value)? Or am I misunderstanding what you're saying? |
@pythonesque Yes, but you can reproduce the semantics of reborrowing with a method that takes |
☔ The latest upstream changes (presumably #24619) made this pull request unmergeable. Please resolve the merge conflicts. |
@pythonesque do you intend to move some of these functions to methods on Block? Should I hold back on reviewing until then? I don't mind passing |
@nrc I actually started doing switching over to making everything methods on |
fn trans<'r, 'blk>(&self, | ||
&mut Block { bl, ref mut fcx }: &mut Block<'r, 'blk, 'tcx>) | ||
-> OptResult<'blk> { | ||
let mut bcx = &mut bl.with(fcx); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit weird - especially to newcomers to trans - we take a Block as parameter, then create a new one, using only the components of the passed Block, then later in the function we use the fields of the same Block again. Either with
needs a better name indicating what is going on, or we need a comment here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pattern (well, similar) was actually already used all over the place prior to this PR. But I'll take a closer look at this particular one.
I could rename it to with_fcx
, if that helps. Note that the reason we do this is to reborrow it; otherwise borrowck yells at me really, really hard.
Wow, that is quite a PR! So, I think it makes sense and I'm in favour of landing. It certainly seems like a win in terms of perf. It still seems a bit messier than I would like (the design of Block, some how, rather than the quality of the code or anything like that), but it doesn't seem that there is a great solution under it all. I'd be keen to know what the Block + methods approach looks like, but I'd be happy to see this land. r=me with the Block/BlockS and with naming issue addressed, unless the inherant impl thing works out. |
Specifically, changing Block -> BlockContext, BlockS -> Block, and Block::with to Block::with_fcx.
@nrc Addressed your comments and synced to latest master. |
Maybe we can refactor terminated: Cell<bool>,
unreachable: Cell<bool>,
/// Is this block part of a landing pad?
is_lpad: bool,
/// AST node-id associated with this block, if any. Used debugging purposes only.
opt_node_id: Option<ast::NodeId>,
Verdict: we should be able to pass around only the |
@eddyb Yes, I also was wondering about the arena. I think I eventually concluded that the references are held onto somewhere in the drop glue code and that trying to refactor that as well was something I could look at after the initial version landed. I'm not 100% sure that all those fields are just caches of the LLVM ones; I would have to look into it. Either way, it seems to me that so long as we're relying on the information living in LLVM, we would still need some sort of lifetime attached (even if only as I think I agree that you could get away with not having an explicit lifetime for the In general: I agree there is lots of refactoring work we can do on top of this change, but I think it will be much easier to figure out what we can and can't get away with after we are passing around |
☔ The latest upstream changes (presumably #25595) made this pull request unmergeable. Please resolve the merge conflicts. |
☔ The latest upstream changes (presumably #25645) made this pull request unmergeable. Please resolve the merge conflicts. |
I started a discuss thread to discuss this approach, since it seems to have some pros and cons: https://internals.rust-lang.org/t/prs-removing-refcells-longer-term-plans/2099 |
☔ The latest upstream changes (presumably #25653) made this pull request unmergeable. Please resolve the merge conflicts. |
Closing due to inactivity, but feel free to reopen with a rebase! |
The
FunctionContext
is now passed around mutably pretty much everywhere.The
RefCell
motherlode in trans is in the local crate context, but I think this part can stand on its own. I did check to see if I could make the local crate context mutable really easily, but after a few tests I think it would require enough additional work that it probably isn't worth delaying this PR submission.