-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Make tcx optional from StableMIR run macro and extend it to accept closures #119833
Conversation
r? @ouz-a (rustbot has picked a reviewer for you, use r? to override) |
pub fn internal<'tcx, S: RustcInternal<'tcx>>(item: S) -> S::T { | ||
with_tables(|tables| item.internal(tables)) | ||
} | ||
|
||
/// Retrieve the internal Rust compiler type context. | ||
/// | ||
/// # Warning | ||
/// | ||
/// This function is unstable, and it's behavior may change at any point. | ||
/// | ||
/// # Panics | ||
/// | ||
/// This function will panic if StableMIR has not been properly initialized. | ||
pub fn tcx<'tcx>() -> TyCtxt<'tcx> { | ||
with_tables(|tables| tables.tcx) | ||
} |
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.
These two functions are unsound. They trivially allow you to create a TyCtxt<'static>
or a Ty<'static>
and move it outside the run!
invocation in safe code.
The only way I see them becoming safe is to use the with_tables
scheme of passing a closure that then gets the item as an argument. This way we can have control over how long the item lives
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.
Indeed. Let me fix that!
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.
I removed tcx()
and added the type context as an argument to internal()
to avoid the issue you just mentioned.
Even though the new solution is a bit hacky, I think its safer and more usable than the with_tables
solution. Let me know what you think.
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.
Oh that's even better!
Simplify the `run` macro to avoid sometimes unnecessary dependency on `TyCtxt`. Instead, users can use the new internal method `tcx()`. Additionally, extend the macro to accept closures that may capture variables. These are non-backward compatible changes, but they only affect internal APIs which are provided today as helper functions until we have a stable API to start the compiler.
I added `tcx` argument to `internal` to force 'tcx to be the same lifetime as TyCtxt. The only other solution I could think is to change this function to be `unsafe`.
8041889
to
2564811
Compare
This comment has been minimized.
This comment has been minimized.
@bors r+ rollup |
/// This function will panic if StableMIR has not been properly initialized. | ||
pub fn internal<'tcx, S: RustcInternal<'tcx>>(tcx: TyCtxt<'tcx>, item: S) -> S::T { | ||
// The tcx argument ensures that the item won't outlive the type context. | ||
let _ = tcx; |
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.
There can be multiple TyCtxt at the same time. You did have to use Lift to ensure that the item comes from the right TyCtxt.
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.
can we actually have them at the same time? Or just after each other? (though I guess the same issue applies there)
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.
But, that is not an issue here, because once the stable mir context shuts down, there is no more mapping of the stable mir type. You may get the wrong rustc type, but it will still be within the TyCtxt.
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.
can we actually have them at the same time?
Yes, you can a new TyCtxt and enter it and then with access to that TyCtxt it should be possible to create a new stable mir context and pass the TyCtxt you entered yourself as argument to internal(). This would allow the returned value outlive the TyCtxt of the stable mir context despite referencing values that are being freed with the rest of the stable mir context.
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.
Ok... I'm amazed our TLS doesn't panic, but just replace the old tls tcx with the new one and switch it back afterwards. I did not expect that.
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.
Just to make sure I understand, there could exist 2 or more TyCtxt
in the same thread, and an item that was interned in one TyCtxt
might outlive the type in a different one.
In that case, we should invoke lift
using the TyCtxt
that was passed to the intern
function. Is that correct?
It also looks like not everything that implements RustcInternal
, implements Lift
, so the intern call will have to be done in the RustcInternal
implementation for types that require so.
If both facts are true, my plan is to mark the RustcInternal
trait as unsafe
and add TyCtxt
as an argument to RustcInternal::internal
as well. It will be up to the RustcInternal
implementation to invoke lift
.
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.
BTW, this change won't be small. Since the changes in this PR are now unrelated to this issue, can we go ahead and merge the current PR and I can create a follow up PR with the solution I described above. I can even revert adding tcx
argument to the internal function if you prefer and add it in the next one.
@bors r- I guess we do need to use |
ac66570
to
cc4ac83
Compare
- Move fix to a separate PR
cc4ac83
to
6a573cb
Compare
@oli-obk I reverted all changes related to |
@rustbot label +S-waiting-on-review -S-waiting-on-author |
@bors r+ |
…li-obk Make tcx optional from StableMIR run macro and extend it to accept closures Change `run` macro to avoid sometimes unnecessary dependency on `TyCtxt`, and introduce `run_with_tcx` to capture use cases where `tcx` is required. Additionally, extend both macros to accept closures that may capture variables. I've also modified the `internal()` method to make it safer, by accepting the type context to force the `'tcx` lifetime to match the context lifetime. These are non-backward compatible changes, but they only affect internal APIs which are provided today as helper functions until we have a stable API to start the compiler.
…li-obk Make tcx optional from StableMIR run macro and extend it to accept closures Change `run` macro to avoid sometimes unnecessary dependency on `TyCtxt`, and introduce `run_with_tcx` to capture use cases where `tcx` is required. Additionally, extend both macros to accept closures that may capture variables. I've also modified the `internal()` method to make it safer, by accepting the type context to force the `'tcx` lifetime to match the context lifetime. These are non-backward compatible changes, but they only affect internal APIs which are provided today as helper functions until we have a stable API to start the compiler.
…iaskrgr Rollup of 7 pull requests Successful merges: - rust-lang#119172 (Detect `NulInCStr` error earlier.) - rust-lang#119833 (Make tcx optional from StableMIR run macro and extend it to accept closures) - rust-lang#119955 (Modify GenericArg and Term structs to use strict provenance rules) - rust-lang#120021 (don't store const var origins for known vars) - rust-lang#120038 (Don't create a separate "basename" when naming and opening a MIR dump file) - rust-lang#120057 (Don't ICE when deducing future output if other errors already occurred) - rust-lang#120073 (Remove spastorino from users_on_vacation) r? `@ghost` `@rustbot` modify labels: rollup
…iaskrgr Rollup of 8 pull requests Successful merges: - rust-lang#119172 (Detect `NulInCStr` error earlier.) - rust-lang#119833 (Make tcx optional from StableMIR run macro and extend it to accept closures) - rust-lang#119967 (Add `PatKind::Err` to AST/HIR) - rust-lang#119978 (Move async closure parameters into the resultant closure's future eagerly) - rust-lang#120021 (don't store const var origins for known vars) - rust-lang#120038 (Don't create a separate "basename" when naming and opening a MIR dump file) - rust-lang#120057 (Don't ICE when deducing future output if other errors already occurred) - rust-lang#120073 (Remove spastorino from users_on_vacation) r? `@ghost` `@rustbot` modify labels: rollup
…iaskrgr Rollup of 8 pull requests Successful merges: - rust-lang#119172 (Detect `NulInCStr` error earlier.) - rust-lang#119833 (Make tcx optional from StableMIR run macro and extend it to accept closures) - rust-lang#119967 (Add `PatKind::Err` to AST/HIR) - rust-lang#119978 (Move async closure parameters into the resultant closure's future eagerly) - rust-lang#120021 (don't store const var origins for known vars) - rust-lang#120038 (Don't create a separate "basename" when naming and opening a MIR dump file) - rust-lang#120057 (Don't ICE when deducing future output if other errors already occurred) - rust-lang#120073 (Remove spastorino from users_on_vacation) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#119833 - celinval:smir-accept-closures, r=oli-obk Make tcx optional from StableMIR run macro and extend it to accept closures Change `run` macro to avoid sometimes unnecessary dependency on `TyCtxt`, and introduce `run_with_tcx` to capture use cases where `tcx` is required. Additionally, extend both macros to accept closures that may capture variables. I've also modified the `internal()` method to make it safer, by accepting the type context to force the `'tcx` lifetime to match the context lifetime. These are non-backward compatible changes, but they only affect internal APIs which are provided today as helper functions until we have a stable API to start the compiler.
The following PRs needed to be addressed: - rust-lang/rust#119833 - rust-lang/rust#119790 Note that the rustc tests are no longer passing, but the failures are unrelated to these changes and need further investigation.
The following PRs needed to be addressed: - rust-lang/rust#119833 - rust-lang/rust#119790 Note that the rustc tests are no longer passing, but the failures are unrelated to these changes and need further investigation.
The following PRs needed to be addressed: - rust-lang/rust#119833 - rust-lang/rust#119790 Note that the rustc tests are no longer passing, but the failures are unrelated to these changes and need further investigation.
Change
run
macro to avoid sometimes unnecessary dependency onTyCtxt
, and introducerun_with_tcx
to capture use cases wheretcx
is required. Additionally, extend both macros to accept closures that may capture variables.I've also modified the
internal()
method to make it safer, by accepting the type context to force the'tcx
lifetime to match the context lifetime.These are non-backward compatible changes, but they only affect internal APIs which are provided today as helper functions until we have a stable API to start the compiler.