-
Notifications
You must be signed in to change notification settings - Fork 533
const-eval.const-expr.borrows: mention indirect places #1865
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
const-eval.const-expr.borrows: mention indirect places #1865
Conversation
9fe65cb
to
9d83c64
Compare
Based on the last commit I added in rust-lang/rust#140942, instead of a list of things we allow, we could consider just saying what is not allowed -- mutable / interior mutable borrows of lifetime-extended places. Maybe that would be better? |
Thanks @RalfJung; @ehuss and talked about this new language. On first pass, it looks pretty good to us. To your question about stating this in terms of what's not allowed, that also had some appeal to us, and we actually think it'd be best in this case to do both, i.e. to state what's allowed, as is done here, and to then also approach the same truth from the other side by stating what's not allowed. We do that in a number of places, and this seems like a good candidate for it, in terms of being as clear as possible. |
I've given that a shot, please let me know what you think. I also realized |
Thanks. Probably we'll want to add some examples here for each. Regarding the "top-level scope" bit, I wonder if there's a more clear way we could say that. We allow, of course, e.g.: struct S;
const fn temp() -> S { S }
const C1: &S = { let y = { let x = &temp(); x }; y };
const C2: &S = 'top: { let y = { let x = &temp(); break 'top x; }; }; That is, there's a distinction between the temporary being created in the top-level scope and being referenced by the final value. |
All of those are immutable references so yes of course we allow them. That doesn't really exercise the clauses this PR is about, though. There are no examples for any of the surrounding text here so I'll not try to figure out the best way to integrate examples into this part of the docs. |
The question is about this change specifically, which is independent of mutability: r[destructors.scope.lifetime-extension.static]
-Lifetime extension also applies to `static` and `const` items, where it makes temporaries live until the end of the program.
+Lifetime extension also applies to the top-level scope of `static` and `const` items, where it makes temporaries live until the end of the program. It seems that the rule for this should be essentially the same as the rule that precedes it, except that we're extending to
(Admittedly, that rule is rather ambiguous itself.) So if this "top-level scope" qualification makes sense for one, then it would seem to make sense for the other. But I think it gets into some ambiguity about "are we talking about the temporary being created in the top-level scope or about the temporary being referenced by the value returned from the top-level scope?". Clearly we don't mean the former. |
We mean "the temporary is extended to the scope outside the const initializer expression". Not sure what is the best way to put that... |
We'll take care of integrating these, but @ehuss and I would be interested if you could provide here, just as a reply, differentiating examples (i.e. examples that fit in exactly one category) for each of the things we're defining here, i.e. transient places, indirect places, places based on static items, and places based on promoted expressions. |
ae67917
to
2ee9fd4
Compare
Thanks. I pushed a clarification to define this in terms of the other rule that touches on this. |
static mut S: i32= 0;
#[allow(static_mut_refs)]
const C: () = {
let mut x = 0;
let mref = &mut x; // reference to transient place
let mref2 = &mut *mref; // reference to indirect place
let sref = unsafe { &mut S }; // reference to static place
let pref: &mut [i32] = &mut []; // reference to promoted
}; |
691ec18
to
846f675
Compare
Thanks @RalfJung for the examples. I've pushed commits to integrate those and some others and to hopefully clarify some language. Let me know if that all looks right. |
bf9bc37
to
07b3859
Compare
In testing, I notice this: ---- const_eval.md - Constant_evaluation::Constant_expressions (line 212) stdout ----
error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed
--> const_eval.md:213:18
|
3 | const C: &[u8] = &mut [];
| ^^^^^^^
error: aborting due to 1 previous error This borrow isn't of an interior mutable temporary. Does this imply a second or a broader exception, you think, or is this covered by something else? |
07b3859
to
c55401b
Compare
It's mutable, but not interior mutable. Though what I find odd is that |
So, uh, looks like we are doing the static const checks before we do promotion? @oli-obk is that expected? That means we should remove promotion from the text and examples in this PR. |
static const checks happen before promotion intentionally. I think they should even be a part of typeck, and I think we should be able to move more of it into typeck |
Okay, looks like I just entirely forgot about that then. That's good, discussing promoteds here got a bit awkward IMO... |
… r=oli-obk const checks for lifetime-extended temporaries: avoid 'top-level scope' terminology This error recently got changed in rust-lang#140942 to use the terminology of "top-level scope", but after further discussion in rust-lang/reference#1865 it seems the reference will not be using that terminology after all. So let's also remove it from the compiler again, and let's focus on what actually happens with these temporaries: their lifetime is extended until the end of the program. r? `@oli-obk` `@traviscross`
… r=oli-obk const checks for lifetime-extended temporaries: avoid 'top-level scope' terminology This error recently got changed in rust-lang#140942 to use the terminology of "top-level scope", but after further discussion in rust-lang/reference#1865 it seems the reference will not be using that terminology after all. So let's also remove it from the compiler again, and let's focus on what actually happens with these temporaries: their lifetime is extended until the end of the program. r? ``@oli-obk`` ``@traviscross``
It seems a rather subtle point to document, given that: const C1: &[u8] = { let x: &'static mut [u8] = &mut []; x }; //~ OK
const C2: &[u8] = { &mut [] }; //~ ERROR |
Rollup merge of #143092 - RalfJung:const-check-lifetime-ext, r=oli-obk const checks for lifetime-extended temporaries: avoid 'top-level scope' terminology This error recently got changed in #140942 to use the terminology of "top-level scope", but after further discussion in rust-lang/reference#1865 it seems the reference will not be using that terminology after all. So let's also remove it from the compiler again, and let's focus on what actually happens with these temporaries: their lifetime is extended until the end of the program. r? ``@oli-obk`` ``@traviscross``
const checks for lifetime-extended temporaries: avoid 'top-level scope' terminology This error recently got changed in rust-lang/rust#140942 to use the terminology of "top-level scope", but after further discussion in rust-lang/reference#1865 it seems the reference will not be using that terminology after all. So let's also remove it from the compiler again, and let's focus on what actually happens with these temporaries: their lifetime is extended until the end of the program. r? ``@oli-obk`` ``@traviscross``
Yeah, that is kind of odd -- the fact that lifetime extension kicks in here means that code that would otherwise have compiled (if there was no lifetime extension) now does not compile. |
c55401b
to
6091e79
Compare
I may yet make some further editorial revisions, but @RalfJung, how does this look? |
8b3722b
to
0d9c1cf
Compare
Rather than talking about lifetime-extended temporaries in the top-level scope of an initializer, which is maybe a bit ambiguous, let's speak directly to the result of the lifetime extension, which is that these temporaries disallowed for borrows would have their lifetimes extended to the end of the program. Let's also speak about place expressions, rather than places, as that's more precise here. We'll add examples throughout. Thanks to RalfJ for the substance of many of these.
0d9c1cf
to
c1f8da5
Compare
Thanks @RalfJung for the follow-up here. |
Update books ## rust-lang/book 3 commits in ef1ce8f87a8b18feb1b6a9cf9a4939a79bde6795..b2d1a0821e12a676b496d61891b8e3d374a8e832 2025-07-08 17:24:41 UTC to 2025-07-02 21:30:57 UTC - Chapter 16 from tech review (rust-lang/book#4438) - WIP ch 17 edits after tech review (rust-lang/book#4319) - Chapter 15 from tech review (rust-lang/book#4433) ## rust-embedded/book 1 commits in 41f688a598a5022b749e23d37f3c524f6a0b28e1..fe88fbb68391a465680dd91109f0a151a1676f3e 2025-07-08 18:54:25 UTC to 2025-07-08 18:54:25 UTC - Clarify usage of #[interrupt] attribute and recommend device crate re… (rust-embedded/book#386) ## rust-lang/nomicon 3 commits in 8b61acfaea822e9ac926190bc8f15791c33336e8..3ff384320598bbe8d8cfe5cb8f18f78a3a3e6b15 2025-07-05 07:34:22 UTC to 2025-07-05 07:13:51 UTC - Add build script part to FFI chapter for more clear and smooth learn … (rust-lang/nomicon#440) - Cleanups for tree example of splitting borrows (rust-lang/nomicon#443) - Handle drop zst (rust-lang/nomicon#425) ## rust-lang/reference 17 commits in e9fc99f107840813916f62e16b3f6d9556e1f2d8..1f45bd41fa6c17b7c048ed6bfe5f168c4311206a 2025-07-11 23:15:51 UTC to 2025-07-01 16:49:33 UTC - mention an important use for the naked attribute (rust-lang/reference#1929) - Array expression repeat operands can be const blocks. (rust-lang/reference#1928) - Document (tuple) struct pattern namespace behavior (rust-lang/reference#1925) - Replace set of en dashes with set of em dashes (rust-lang/reference#1926) - Update `should_panic` to use the attribute template (rust-lang/reference#1882) - const-eval.const-expr.borrows: mention indirect places (rust-lang/reference#1865) - associated-items.md: remove redundant word (rust-lang/reference#1874) - introduction.md: replace hard-to-read example (rust-lang/reference#1873) - typo (rust-lang/reference#1924) - Update `ignore` to use the attribute template (rust-lang/reference#1881) - Update `test` to use the attribute template (rust-lang/reference#1880) - Update `cfg_attr` to use the attribute template (rust-lang/reference#1879) - Update `cfg` to use the attribute template (rust-lang/reference#1878) - allow constants to refer to mutable/external memory, but reject such constants as patterns (rust-lang/reference#1859) - Remove outdated comment about non-copy unions (rust-lang/reference#1872) - Add a template for documenting attributes (rust-lang/reference#1877) - Switch enum grammar to use "variant" (rust-lang/reference#1876) ## rust-lang/rust-by-example 1 commits in 288b4e4948add43f387cad35adc7b1c54ca6fe12..e386be5f44af711854207c11fdd61bb576270b04 2025-07-04 23:17:15 UTC to 2025-07-04 23:17:15 UTC - Update Chinese translations (rust-lang/rust-by-example#1943)
Update books ## rust-lang/book 3 commits in ef1ce8f87a8b18feb1b6a9cf9a4939a79bde6795..b2d1a0821e12a676b496d61891b8e3d374a8e832 2025-07-08 17:24:41 UTC to 2025-07-02 21:30:57 UTC - Chapter 16 from tech review (rust-lang/book#4438) - WIP ch 17 edits after tech review (rust-lang/book#4319) - Chapter 15 from tech review (rust-lang/book#4433) ## rust-embedded/book 1 commits in 41f688a598a5022b749e23d37f3c524f6a0b28e1..fe88fbb68391a465680dd91109f0a151a1676f3e 2025-07-08 18:54:25 UTC to 2025-07-08 18:54:25 UTC - Clarify usage of #[interrupt] attribute and recommend device crate re… (rust-embedded/book#386) ## rust-lang/nomicon 3 commits in 8b61acfaea822e9ac926190bc8f15791c33336e8..3ff384320598bbe8d8cfe5cb8f18f78a3a3e6b15 2025-07-05 07:34:22 UTC to 2025-07-05 07:13:51 UTC - Add build script part to FFI chapter for more clear and smooth learn … (rust-lang/nomicon#440) - Cleanups for tree example of splitting borrows (rust-lang/nomicon#443) - Handle drop zst (rust-lang/nomicon#425) ## rust-lang/reference 17 commits in e9fc99f107840813916f62e16b3f6d9556e1f2d8..1f45bd41fa6c17b7c048ed6bfe5f168c4311206a 2025-07-11 23:15:51 UTC to 2025-07-01 16:49:33 UTC - mention an important use for the naked attribute (rust-lang/reference#1929) - Array expression repeat operands can be const blocks. (rust-lang/reference#1928) - Document (tuple) struct pattern namespace behavior (rust-lang/reference#1925) - Replace set of en dashes with set of em dashes (rust-lang/reference#1926) - Update `should_panic` to use the attribute template (rust-lang/reference#1882) - const-eval.const-expr.borrows: mention indirect places (rust-lang/reference#1865) - associated-items.md: remove redundant word (rust-lang/reference#1874) - introduction.md: replace hard-to-read example (rust-lang/reference#1873) - typo (rust-lang/reference#1924) - Update `ignore` to use the attribute template (rust-lang/reference#1881) - Update `test` to use the attribute template (rust-lang/reference#1880) - Update `cfg_attr` to use the attribute template (rust-lang/reference#1879) - Update `cfg` to use the attribute template (rust-lang/reference#1878) - allow constants to refer to mutable/external memory, but reject such constants as patterns (rust-lang/reference#1859) - Remove outdated comment about non-copy unions (rust-lang/reference#1872) - Add a template for documenting attributes (rust-lang/reference#1877) - Switch enum grammar to use "variant" (rust-lang/reference#1876) ## rust-lang/rust-by-example 1 commits in 288b4e4948add43f387cad35adc7b1c54ca6fe12..e386be5f44af711854207c11fdd61bb576270b04 2025-07-04 23:17:15 UTC to 2025-07-04 23:17:15 UTC - Update Chinese translations (rust-lang/rust-by-example#1943)
Follow-up to #1858.