Skip to content

Commit 96d1330

Browse files
committed
Split may_dangle
1 parent c0a2cef commit 96d1330

File tree

1 file changed

+154
-0
lines changed

1 file changed

+154
-0
lines changed

text/3414-split-maydangle.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
- Feature Name: `split_maydangle`
2+
- Start Date: 2023-02-13
3+
- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)
4+
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
Add `#[needs_drop]`, ignore `PhantomData` for outlives requirements.
10+
11+
# Motivation
12+
[motivation]: #motivation
13+
14+
This fails to compile:
15+
16+
```rust
17+
use core::marker::PhantomData;
18+
19+
struct PrintOnDrop<'s>(&'s str);
20+
impl<'s> Drop for PrintOnDrop<'s> {
21+
fn drop(&mut self) {
22+
println!("{}", self.0);
23+
}
24+
}
25+
26+
fn to_pd<T>(_: T) -> PhantomData<T> {
27+
PhantomData
28+
}
29+
30+
pub fn foo() {
31+
let mut x;
32+
{
33+
let s = String::from("temporary");
34+
let p = PrintOnDrop(&s);
35+
x = (to_pd(p), String::new());
36+
}
37+
}
38+
```
39+
40+
And yet, this compiles:
41+
42+
```rust
43+
use core::marker::PhantomData;
44+
45+
struct PrintOnDrop<'s>(&'s str);
46+
impl<'s> Drop for PrintOnDrop<'s> {
47+
fn drop(&mut self) {
48+
println!("{}", self.0);
49+
}
50+
}
51+
52+
fn to_pd<T>(_: T) -> PhantomData<T> {
53+
PhantomData
54+
}
55+
56+
pub fn foo() {
57+
let mut x;
58+
{
59+
let s = String::from("temporary");
60+
let p = PrintOnDrop(&s);
61+
x = (to_pd(p), ());
62+
}
63+
}
64+
```
65+
66+
Since the values in the tuple are unrelated, they should not affect each other.
67+
68+
# Guide-level explanation
69+
[guide-level-explanation]: #guide-level-explanation
70+
71+
A type marked `#[needs_drop]` gets checked for liveness at drop. This is
72+
necessary for `Vec`:
73+
74+
```rust
75+
struct Vec<T> {
76+
...
77+
}
78+
79+
unsafe impl<#[needs_drop] #[may_dangle] T> Drop for Vec<T> {
80+
fn drop(&mut self) {
81+
...
82+
}
83+
}
84+
```
85+
86+
So that this compiles:
87+
88+
```rust
89+
fn main() {
90+
let mut v = vec![];
91+
{
92+
v.push(&String::from("temporary"));
93+
}
94+
}
95+
```
96+
97+
But this cannot compile, as it would be unsound:
98+
99+
```rust
100+
struct PrintOnDrop<'s>(&'s str);
101+
impl<'s> Drop for PrintOnDrop<'s> {
102+
fn drop(&mut self) {
103+
println!("{}", self.0);
104+
}
105+
}
106+
107+
fn main() {
108+
let mut v = vec![];
109+
{
110+
v.push(PrintOnDrop(&*String::from("temporary")));
111+
}
112+
}
113+
```
114+
115+
# Reference-level explanation
116+
[reference-level-explanation]: #reference-level-explanation
117+
118+
This RFC removes the dropck/outlives constraints from `PhantomData` and moves
119+
them into the relevant `Drop` impls instead.
120+
121+
# Drawbacks
122+
[drawbacks]: #drawbacks
123+
124+
Requires mild churn to update things to the new way. Failing to update wouldn't
125+
break existing code, but would allow unsound code to compile.
126+
127+
# Rationale and alternatives
128+
[rationale-and-alternatives]: #rationale-and-alternatives
129+
130+
A type which doesn't need drop should never have dropck/outlives contraints,
131+
but due to the rushed way in which `may_dangle` was implemented, `PhantomData`
132+
ended up having this unfortunate behaviour. This RFC removes this behaviour and
133+
allows strictly more code to compile.
134+
135+
# Prior art
136+
[prior-art]: #prior-art
137+
138+
- Compiler MCP 563: It is the exact same thing as this RFC, but a full RFC
139+
seemed appropriate due to observable changes on stable, even if they are
140+
fairly obscure.
141+
- Unsound dropck elaboration for `BTreeMap`: <https://github.com/rust-lang/rust/pull/99413>
142+
- `may_dangle`: RFC 1238, RFC 1327
143+
- This is effectively split from RFC PR 3390 and is not intended for
144+
stabilization.
145+
146+
# Unresolved questions
147+
[unresolved-questions]: #unresolved-questions
148+
149+
N/A
150+
151+
# Future possibilities
152+
[future-possibilities]: #future-possibilities
153+
154+
The full RFC 3390, and stabilization.

0 commit comments

Comments
 (0)