Skip to content

Commit d84e340

Browse files
committed
Make VaListImpl<'f> invariant over the 'f lifetime
1 parent 71f9384 commit d84e340

File tree

3 files changed

+97
-42
lines changed

3 files changed

+97
-42
lines changed

src/libcore/ffi.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ impl fmt::Debug for c_void {
6060
#[lang = "va_list"]
6161
pub struct VaListImpl<'f> {
6262
ptr: *mut c_void,
63-
_marker: PhantomData<&'f c_void>,
63+
64+
// Invariant over `'f`, so each `VaListImpl<'f>` object is tied to
65+
// the region of the function it's defined in
66+
_marker: PhantomData<&'f mut &'f c_void>,
6467
}
6568

6669
#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
@@ -96,7 +99,7 @@ pub struct VaListImpl<'f> {
9699
vr_top: *mut c_void,
97100
gr_offs: i32,
98101
vr_offs: i32,
99-
_marker: PhantomData<&'f c_void>,
102+
_marker: PhantomData<&'f mut &'f c_void>,
100103
}
101104

102105
/// PowerPC ABI implementation of a `va_list`.
@@ -114,7 +117,7 @@ pub struct VaListImpl<'f> {
114117
reserved: u16,
115118
overflow_arg_area: *mut c_void,
116119
reg_save_area: *mut c_void,
117-
_marker: PhantomData<&'f c_void>,
120+
_marker: PhantomData<&'f mut &'f c_void>,
118121
}
119122

120123
/// x86_64 ABI implementation of a `va_list`.
@@ -131,7 +134,7 @@ pub struct VaListImpl<'f> {
131134
fp_offset: i32,
132135
overflow_arg_area: *mut c_void,
133136
reg_save_area: *mut c_void,
134-
_marker: PhantomData<&'f c_void>,
137+
_marker: PhantomData<&'f mut &'f c_void>,
135138
}
136139

137140
/// asm.js ABI implementation of a `va_list`.
@@ -148,7 +151,7 @@ pub struct VaListImpl<'f> {
148151
#[lang = "va_list"]
149152
pub struct VaListImpl<'f> {
150153
inner: [crate::mem::MaybeUninit<i32>; 4],
151-
_marker: PhantomData<&'f c_void>,
154+
_marker: PhantomData<&'f mut &'f c_void>,
152155
}
153156

154157
#[cfg(all(target_arch = "asmjs", not(windows)))]

src/test/ui/c-variadic/variadic-ffi-4.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) {
1818

1919
pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
2020
*ap0 = ap1; //~ ERROR: mismatched types
21+
//~^ ERROR: mismatched types
2122
}
2223

2324
pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
@@ -29,5 +30,6 @@ pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...
2930
}
3031

3132
pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
32-
*ap0 = ap1.clone(); //~ ERROR: cannot infer an appropriate lifetime
33+
*ap0 = ap1.clone(); //~ ERROR: mismatched types
34+
//~^ ERROR: mismatched types
3335
}

src/test/ui/c-variadic/variadic-ffi-4.stderr

+86-36
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,51 @@ note: the anonymous lifetime #3 defined on the function body at 19:1...
5252
|
5353
LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
5454
LL | | *ap0 = ap1;
55+
LL | |
5556
LL | | }
5657
| |_^
5758
note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 19:1
5859
--> $DIR/variadic-ffi-4.rs:19:1
5960
|
6061
LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
6162
LL | | *ap0 = ap1;
63+
LL | |
64+
LL | | }
65+
| |_^
66+
67+
error[E0308]: mismatched types
68+
--> $DIR/variadic-ffi-4.rs:20:12
69+
|
70+
LL | *ap0 = ap1;
71+
| ^^^ lifetime mismatch
72+
|
73+
= note: expected type `core::ffi::VaListImpl<'_>`
74+
found type `core::ffi::VaListImpl<'_>`
75+
note: the anonymous lifetime #2 defined on the function body at 19:1...
76+
--> $DIR/variadic-ffi-4.rs:19:1
77+
|
78+
LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
79+
LL | | *ap0 = ap1;
80+
LL | |
81+
LL | | }
82+
| |_^
83+
note: ...does not necessarily outlive the anonymous lifetime #3 defined on the function body at 19:1
84+
--> $DIR/variadic-ffi-4.rs:19:1
85+
|
86+
LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
87+
LL | | *ap0 = ap1;
88+
LL | |
6289
LL | | }
6390
| |_^
6491

6592
error[E0490]: a value of type `core::ffi::VaListImpl<'_>` is borrowed for too long
66-
--> $DIR/variadic-ffi-4.rs:24:11
93+
--> $DIR/variadic-ffi-4.rs:25:11
6794
|
6895
LL | ap0 = &mut ap1;
6996
| ^^^^^^^^
7097
|
71-
note: the type is valid for the anonymous lifetime #1 defined on the function body at 23:1
72-
--> $DIR/variadic-ffi-4.rs:23:1
98+
note: the type is valid for the anonymous lifetime #1 defined on the function body at 24:1
99+
--> $DIR/variadic-ffi-4.rs:24:1
73100
|
74101
LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
75102
LL | | ap0 = &mut ap1;
@@ -79,8 +106,8 @@ LL | |
79106
LL | |
80107
LL | | }
81108
| |_^
82-
note: but the borrow lasts for the anonymous lifetime #3 defined on the function body at 23:1
83-
--> $DIR/variadic-ffi-4.rs:23:1
109+
note: but the borrow lasts for the anonymous lifetime #3 defined on the function body at 24:1
110+
--> $DIR/variadic-ffi-4.rs:24:1
84111
|
85112
LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
86113
LL | | ap0 = &mut ap1;
@@ -92,15 +119,15 @@ LL | | }
92119
| |_^
93120

94121
error[E0308]: mismatched types
95-
--> $DIR/variadic-ffi-4.rs:24:11
122+
--> $DIR/variadic-ffi-4.rs:25:11
96123
|
97124
LL | ap0 = &mut ap1;
98125
| ^^^^^^^^ lifetime mismatch
99126
|
100127
= note: expected type `&mut core::ffi::VaListImpl<'_>`
101128
found type `&mut core::ffi::VaListImpl<'_>`
102-
note: the anonymous lifetime #3 defined on the function body at 23:1...
103-
--> $DIR/variadic-ffi-4.rs:23:1
129+
note: the anonymous lifetime #3 defined on the function body at 24:1...
130+
--> $DIR/variadic-ffi-4.rs:24:1
104131
|
105132
LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
106133
LL | | ap0 = &mut ap1;
@@ -110,8 +137,8 @@ LL | |
110137
LL | |
111138
LL | | }
112139
| |_^
113-
note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 23:1
114-
--> $DIR/variadic-ffi-4.rs:23:1
140+
note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 24:1
141+
--> $DIR/variadic-ffi-4.rs:24:1
115142
|
116143
LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
117144
LL | | ap0 = &mut ap1;
@@ -123,15 +150,15 @@ LL | | }
123150
| |_^
124151

125152
error[E0308]: mismatched types
126-
--> $DIR/variadic-ffi-4.rs:24:11
153+
--> $DIR/variadic-ffi-4.rs:25:11
127154
|
128155
LL | ap0 = &mut ap1;
129156
| ^^^^^^^^ lifetime mismatch
130157
|
131158
= note: expected type `&mut core::ffi::VaListImpl<'_>`
132159
found type `&mut core::ffi::VaListImpl<'_>`
133-
note: the anonymous lifetime #2 defined on the function body at 23:1...
134-
--> $DIR/variadic-ffi-4.rs:23:1
160+
note: the anonymous lifetime #2 defined on the function body at 24:1...
161+
--> $DIR/variadic-ffi-4.rs:24:1
135162
|
136163
LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
137164
LL | | ap0 = &mut ap1;
@@ -141,8 +168,8 @@ LL | |
141168
LL | |
142169
LL | | }
143170
| |_^
144-
note: ...does not necessarily outlive the anonymous lifetime #3 defined on the function body at 23:1
145-
--> $DIR/variadic-ffi-4.rs:23:1
171+
note: ...does not necessarily outlive the anonymous lifetime #3 defined on the function body at 24:1
172+
--> $DIR/variadic-ffi-4.rs:24:1
146173
|
147174
LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
148175
LL | | ap0 = &mut ap1;
@@ -154,13 +181,13 @@ LL | | }
154181
| |_^
155182

156183
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
157-
--> $DIR/variadic-ffi-4.rs:24:11
184+
--> $DIR/variadic-ffi-4.rs:25:11
158185
|
159186
LL | ap0 = &mut ap1;
160187
| ^^^^^^^^
161188
|
162-
note: first, the lifetime cannot outlive the anonymous lifetime #3 defined on the function body at 23:1...
163-
--> $DIR/variadic-ffi-4.rs:23:1
189+
note: first, the lifetime cannot outlive the anonymous lifetime #3 defined on the function body at 24:1...
190+
--> $DIR/variadic-ffi-4.rs:24:1
164191
|
165192
LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
166193
LL | | ap0 = &mut ap1;
@@ -171,12 +198,12 @@ LL | |
171198
LL | | }
172199
| |_^
173200
note: ...so that the type `core::ffi::VaListImpl<'_>` is not borrowed for too long
174-
--> $DIR/variadic-ffi-4.rs:24:11
201+
--> $DIR/variadic-ffi-4.rs:25:11
175202
|
176203
LL | ap0 = &mut ap1;
177204
| ^^^^^^^^
178-
note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the function body at 23:1...
179-
--> $DIR/variadic-ffi-4.rs:23:1
205+
note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the function body at 24:1...
206+
--> $DIR/variadic-ffi-4.rs:24:1
180207
|
181208
LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
182209
LL | | ap0 = &mut ap1;
@@ -187,39 +214,62 @@ LL | |
187214
LL | | }
188215
| |_^
189216
note: ...so that reference does not outlive borrowed content
190-
--> $DIR/variadic-ffi-4.rs:24:11
217+
--> $DIR/variadic-ffi-4.rs:25:11
191218
|
192219
LL | ap0 = &mut ap1;
193220
| ^^^^^^^^
194221

195-
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
196-
--> $DIR/variadic-ffi-4.rs:32:16
222+
error[E0308]: mismatched types
223+
--> $DIR/variadic-ffi-4.rs:33:12
197224
|
198225
LL | *ap0 = ap1.clone();
199-
| ^^^^^
226+
| ^^^^^^^^^^^ lifetime mismatch
200227
|
201-
note: first, the lifetime cannot outlive the anonymous lifetime #3 defined on the function body at 31:1...
202-
--> $DIR/variadic-ffi-4.rs:31:1
228+
= note: expected type `core::ffi::VaListImpl<'_>`
229+
found type `core::ffi::VaListImpl<'_>`
230+
note: the anonymous lifetime #3 defined on the function body at 32:1...
231+
--> $DIR/variadic-ffi-4.rs:32:1
203232
|
204233
LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
205234
LL | | *ap0 = ap1.clone();
235+
LL | |
206236
LL | | }
207237
| |_^
208-
= note: ...so that the types are compatible:
209-
expected &core::ffi::VaListImpl<'_>
210-
found &core::ffi::VaListImpl<'_>
211-
note: but, the lifetime must be valid for the anonymous lifetime #2 defined on the function body at 31:1...
212-
--> $DIR/variadic-ffi-4.rs:31:1
238+
note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 32:1
239+
--> $DIR/variadic-ffi-4.rs:32:1
213240
|
214241
LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
215242
LL | | *ap0 = ap1.clone();
243+
LL | |
244+
LL | | }
245+
| |_^
246+
247+
error[E0308]: mismatched types
248+
--> $DIR/variadic-ffi-4.rs:33:12
249+
|
250+
LL | *ap0 = ap1.clone();
251+
| ^^^^^^^^^^^ lifetime mismatch
252+
|
253+
= note: expected type `core::ffi::VaListImpl<'_>`
254+
found type `core::ffi::VaListImpl<'_>`
255+
note: the anonymous lifetime #2 defined on the function body at 32:1...
256+
--> $DIR/variadic-ffi-4.rs:32:1
257+
|
258+
LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
259+
LL | | *ap0 = ap1.clone();
260+
LL | |
261+
LL | | }
262+
| |_^
263+
note: ...does not necessarily outlive the anonymous lifetime #3 defined on the function body at 32:1
264+
--> $DIR/variadic-ffi-4.rs:32:1
265+
|
266+
LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
267+
LL | | *ap0 = ap1.clone();
268+
LL | |
216269
LL | | }
217270
| |_^
218-
= note: ...so that the expression is assignable:
219-
expected core::ffi::VaListImpl<'_>
220-
found core::ffi::VaListImpl<'_>
221271

222-
error: aborting due to 9 previous errors
272+
error: aborting due to 11 previous errors
223273

224274
Some errors have detailed explanations: E0308, E0621.
225275
For more information about an error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)