-
Notifications
You must be signed in to change notification settings - Fork 13.3k
borrow checking not transparent to inlining #16594
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
Comments
This strikes me as a bit of a feature. I would be unhappy if changing the implementation details of a function (or a function called by a function... etc), suddenly caused a user of that function to fail borrow-checking. Especially since they'd only be passing borrow-checking because they were being clever (or, much more likely: lucky). As it stands now, the signature of the function is sufficient to identify all the ownership consequences of calling the function, which is nice. |
It means there are patterns of common behavior that can't be factored out without aggravating the borrow checker. I have code like this:
If I do this in more than a few places, it would be nice to factor this out into a function, but this isn't valid, regardless of how I define
I could use a macro to call the real function:
But that's kind of cumbersome. Maybe this only makes sense within the context of implementing class internals, but in that case, I don't think it's really clever or lucky for me to rely on some underlying principle of how another function was implemented, and I certainly want the build breaking if those assumptions change. I'd at least like the option of writing functions with "deep" borrow checking, to avoid the impending boilerplate of writing "static" functions and then writing macros to call them. |
"refinement types" would address this (i.e. a method could dictate exactly which fields it touched). Another approach is factoring out the functionality into distinct structs, so it would be |
refinement types sound like what I want! The common factoring approach makes sense in some scenarios (and this pressure from the borrow checker has definitely caused me to factor into smaller structs in some places), but it's not universally applicable - in the mob example above, it doesn't really make immediate sense to further couple any of those things together (except maybe the gl buffers into the gl context). Ultimately a struct is composed of some fundamental and distinct units that are going to be used together, like I think it makes sense to have "deeper" borrow checking as an opt-in (e.g. via explicit typing) - again, I've definitely liked the push back from the borrow checker as a default. |
It's especially strange-looking with closures:
Especially when the solution is manually borrowing the individual parts of the struct:
|
Closing in favor of the refinement types RFC issue: rust-lang/rfcs#671 |
The borrow checker gives different results when functions are manually inlined, giving confusing or annoying results.
The following compiles:
The following does not:
I don't believe this to be a duplicate of #6393, because this has not only to do with scoping, but also the fact that a member function always borrows all of
self
.The text was updated successfully, but these errors were encountered: