This repository was archived by the owner on Apr 5, 2024. It is now read-only.
File tree 4 files changed +101
-0
lines changed
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