This repository was archived by the owner on Apr 5, 2024. It is now read-only.
File tree Expand file tree Collapse file tree 4 files changed +101
-0
lines changed Expand file tree Collapse file tree 4 files changed +101
-0
lines changed Original file line number Diff line number Diff line change 1+ ### Example
2+
3+ ```
4+ fn f_mut_pedantic<'s>(&'s mut self) -> &'s mut Self {
5+ let captured_self = self as *mut Self;
6+ unsafe { &mut *((*captured_self).f() as *const Self as *mut Self) }
7+ }
8+ ```
9+
10+ ### Explanation
11+
12+ More explicit variation on [ f_mut_should_work.md] ( f_mut_should_work.md ) .
13+
14+ ### Source
15+
16+ https://github.com/rust-lang/rust/issues/30424#issuecomment-167009462
Original file line number Diff line number Diff line change 1+ ### Example
2+
3+ ```
4+ fn f(&self) -> &Self { self }
5+ fn f_mut_should_work<'s>(&'s mut self) -> &'s mut Self {
6+ let ret = unsafe { &mut *(self.f() as *const Self as *mut Self) };
7+ ret // β-expansion should have no effect
8+ }
9+ ```
10+
11+ (In the case of a compiler transform, include the transformed source
12+ code as well.)
13+
14+ ### Explanation
15+
16+ - ` self ` is borrowed only within the unsafe block
17+ - on second line, both ` ret ` and ` self ` are live mutable pointers to the same place.
18+
19+ Could be considered UB because multiple invalid aliases are * in
20+ scope* , but then they are never used. See also
21+ [ f_mut_unsure.md] ( f_mut_unsure.md ) .
22+
23+ ### Source
24+
25+ https://github.com/rust-lang/rust/issues/30424#issuecomment-167009014
26+
Original file line number Diff line number Diff line change 1+ ### Example
2+
3+ ```
4+ fn f(&self) -> &Self { self }
5+ fn f_mut_unsure<'s>(&'s mut self) -> &'s mut Self {
6+ let ret = unsafe { transmute::<&Self, &'s mut Self>(self.f()) };
7+ ret // β-expansion should have no effect
8+ }
9+ ```
10+
11+ ### Explanation
12+
13+ - ` self ` is borrowed only within the unsafe block
14+ - on second line, both ` ret ` and ` self ` are live mutable pointers to the same place.
15+ - reborrow of ` self ` would be another alias, alive just after the return from transmute
16+ - this is what is linted against
17+
18+ Under "instant death" rules, both are UB, so we can't have that.
19+
20+ Under the access-based rules, both are fine.
21+
22+ We had a proposal flying around that &-references use instant death
23+ and &mut use some variant of access-based, which would make the first
24+ UB and the second safe.
25+
26+ ### Source
27+
28+ https://github.com/rust-lang/rust/issues/30424#issuecomment-167009014
Original file line number Diff line number Diff line change 1+ ### Example
2+
3+ ```
4+ #[derive(Debug,Copy,Clone)]
5+ struct Foo {
6+ bar: Bar
7+ }
8+ #[derive(Debug,Copy,Clone)]
9+ struct Bar {
10+ // lots of data
11+ }
12+ fn doit() -> u32 {
13+ let foo = Foo { bar: make_bar() };
14+ debug!("{}", &foo);
15+ match foo {
16+ Foo { bar } => frobnicate(&mut bar)
17+ };
18+ }
19+ ```
20+
21+ ### Explanation
22+
23+ In the function ` doit ` , we would like the compiler to be able to make
24+ ` bar ` binding point to ` foo.bar ` in place. But if the ` debug! ` macro
25+ should cast the ` &foo ` to ` *const Foo ` and keep a reference, it could
26+ observe the change. Is it allowed to do that?
27+
28+ ### Source
29+
30+ https://github.com/rust-lang/rust/issues/30424#issuecomment-167009462
31+
You can’t perform that action at this time.
0 commit comments