@@ -18,11 +18,7 @@ use std::borrow::Cow;
18
18
19
19
type McfResult = Result<(), (Span, Cow<'static, str>)>;
20
20
21
- pub fn is_min_const_fn<'a, 'tcx>(
22
- tcx: TyCtxt<'tcx>,
23
- body: &'a Body<'tcx>,
24
- msrv: Option<RustcVersion>,
25
- ) -> McfResult {
21
+ pub fn is_min_const_fn<'a, 'tcx>(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv: Option<RustcVersion>) -> McfResult {
26
22
let def_id = body.source.def_id();
27
23
let mut current = def_id;
28
24
loop {
@@ -37,18 +33,10 @@ pub fn is_min_const_fn<'a, 'tcx>(
37
33
| ty::PredicateKind::ConstEquate(..)
38
34
| ty::PredicateKind::Trait(..)
39
35
| ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
40
- ty::PredicateKind::ObjectSafe(_) => {
41
- panic!("object safe predicate on function: {:#?}", predicate)
42
- }
43
- ty::PredicateKind::ClosureKind(..) => {
44
- panic!("closure kind predicate on function: {:#?}", predicate)
45
- }
46
- ty::PredicateKind::Subtype(_) => {
47
- panic!("subtype predicate on function: {:#?}", predicate)
48
- }
49
- ty::PredicateKind::Coerce(_) => {
50
- panic!("coerce predicate on function: {:#?}", predicate)
51
- }
36
+ ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {:#?}", predicate),
37
+ ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {:#?}", predicate),
38
+ ty::PredicateKind::Subtype(_) => panic!("subtype predicate on function: {:#?}", predicate),
39
+ ty::PredicateKind::Coerce(_) => panic!("coerce predicate on function: {:#?}", predicate),
52
40
}
53
41
}
54
42
match predicates.parent {
@@ -89,23 +77,22 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
89
77
match ty.kind() {
90
78
ty::Ref(_, _, hir::Mutability::Mut) => {
91
79
return Err((span, "mutable references in const fn are unstable".into()));
92
- }
80
+ },
93
81
ty::Opaque(..) => return Err((span, "`impl Trait` in const fn is unstable".into())),
94
82
ty::FnPtr(..) => {
95
83
return Err((span, "function pointers in const fn are unstable".into()));
96
- }
84
+ },
97
85
ty::Dynamic(preds, _, _) => {
98
86
for pred in preds.iter() {
99
87
match pred.skip_binder() {
100
- ty::ExistentialPredicate::AutoTrait(_)
101
- | ty::ExistentialPredicate::Projection(_) => {
88
+ ty::ExistentialPredicate::AutoTrait(_) | ty::ExistentialPredicate::Projection(_) => {
102
89
return Err((
103
90
span,
104
91
"trait bounds other than `Sized` \
105
92
on const fn parameters are unstable"
106
93
.into(),
107
94
));
108
- }
95
+ },
109
96
ty::ExistentialPredicate::Trait(trait_ref) => {
110
97
if Some(trait_ref.def_id) != tcx.lang_items().sized_trait() {
111
98
return Err((
@@ -115,11 +102,11 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
115
102
.into(),
116
103
));
117
104
}
118
- }
105
+ },
119
106
}
120
107
}
121
- }
122
- _ => {}
108
+ },
109
+ _ => {},
123
110
}
124
111
}
125
112
Ok(())
@@ -133,13 +120,10 @@ fn check_rvalue<'tcx>(
133
120
span: Span,
134
121
) -> McfResult {
135
122
match rvalue {
136
- Rvalue::ThreadLocalRef(_) => {
137
- Err((span, "cannot access thread local storage in const fn".into()))
138
- }
139
- Rvalue::Len(place)
140
- | Rvalue::Discriminant(place)
141
- | Rvalue::Ref(_, _, place)
142
- | Rvalue::AddressOf(_, place) => check_place(tcx, *place, span, body),
123
+ Rvalue::ThreadLocalRef(_) => Err((span, "cannot access thread local storage in const fn".into())),
124
+ Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
125
+ check_place(tcx, *place, span, body)
126
+ },
143
127
Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body),
144
128
Rvalue::Repeat(operand, _)
145
129
| Rvalue::Use(operand)
@@ -152,9 +136,7 @@ fn check_rvalue<'tcx>(
152
136
) => check_operand(tcx, operand, span, body),
153
137
Rvalue::Cast(
154
138
CastKind::Pointer(
155
- PointerCast::UnsafeFnPointer
156
- | PointerCast::ClosureFnPointer(_)
157
- | PointerCast::ReifyFnPointer,
139
+ PointerCast::UnsafeFnPointer | PointerCast::ClosureFnPointer(_) | PointerCast::ReifyFnPointer,
158
140
),
159
141
_,
160
142
_,
@@ -164,10 +146,7 @@ fn check_rvalue<'tcx>(
164
146
deref_ty.ty
165
147
} else {
166
148
// We cannot allow this for now.
167
- return Err((
168
- span,
169
- "unsizing casts are only allowed for references right now".into(),
170
- ));
149
+ return Err((span, "unsizing casts are only allowed for references right now".into()));
171
150
};
172
151
let unsized_ty = tcx.struct_tail_erasing_lifetimes(pointee_ty, tcx.param_env(def_id));
173
152
if let ty::Slice(_) | ty::Str = unsized_ty.kind() {
@@ -178,14 +157,14 @@ fn check_rvalue<'tcx>(
178
157
// We just can't allow trait objects until we have figured out trait method calls.
179
158
Err((span, "unsizing casts are not allowed in const fn".into()))
180
159
}
181
- }
160
+ },
182
161
Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => {
183
162
Err((span, "casting pointers to ints is unstable in const fn".into()))
184
- }
163
+ },
185
164
Rvalue::Cast(CastKind::DynStar, _, _) => {
186
165
// FIXME(dyn-star)
187
166
unimplemented!()
188
- }
167
+ },
189
168
// binops are fine on integers
190
169
Rvalue::BinaryOp(_, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(_, box (lhs, rhs)) => {
191
170
check_operand(tcx, lhs, span, body)?;
@@ -194,26 +173,27 @@ fn check_rvalue<'tcx>(
194
173
if ty.is_integral() || ty.is_bool() || ty.is_char() {
195
174
Ok(())
196
175
} else {
197
- Err((span, "only int, `bool` and `char` operations are stable in const fn".into()))
176
+ Err((
177
+ span,
178
+ "only int, `bool` and `char` operations are stable in const fn".into(),
179
+ ))
198
180
}
199
- }
200
- Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) | Rvalue::ShallowInitBox(_, _) => {
201
- Ok(())
202
- }
181
+ },
182
+ Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) | Rvalue::ShallowInitBox(_, _) => Ok(()),
203
183
Rvalue::UnaryOp(_, operand) => {
204
184
let ty = operand.ty(body, tcx);
205
185
if ty.is_integral() || ty.is_bool() {
206
186
check_operand(tcx, operand, span, body)
207
187
} else {
208
188
Err((span, "only int and `bool` operations are stable in const fn".into()))
209
189
}
210
- }
190
+ },
211
191
Rvalue::Aggregate(_, operands) => {
212
192
for operand in operands {
213
193
check_operand(tcx, operand, span, body)?;
214
194
}
215
195
Ok(())
216
- }
196
+ },
217
197
}
218
198
}
219
199
@@ -228,7 +208,7 @@ fn check_statement<'tcx>(
228
208
StatementKind::Assign(box (place, rval)) => {
229
209
check_place(tcx, *place, span, body)?;
230
210
check_rvalue(tcx, body, def_id, rval, span)
231
- }
211
+ },
232
212
233
213
StatementKind::FakeRead(box (_, place)) => check_place(tcx, *place, span, body),
234
214
// just an assignment
@@ -238,15 +218,13 @@ fn check_statement<'tcx>(
238
218
239
219
StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => check_operand(tcx, op, span, body),
240
220
241
- StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
242
- dst,
243
- src,
244
- count,
245
- }) => {
221
+ StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(
222
+ rustc_middle::mir::CopyNonOverlapping { dst, src, count },
223
+ )) => {
246
224
check_operand(tcx, dst, span, body)?;
247
225
check_operand(tcx, src, span, body)?;
248
226
check_operand(tcx, count, span, body)
249
- }
227
+ },
250
228
// These are all NOPs
251
229
StatementKind::StorageLive(_)
252
230
| StatementKind::StorageDead(_)
@@ -257,12 +235,7 @@ fn check_statement<'tcx>(
257
235
}
258
236
}
259
237
260
- fn check_operand<'tcx>(
261
- tcx: TyCtxt<'tcx>,
262
- operand: &Operand<'tcx>,
263
- span: Span,
264
- body: &Body<'tcx>,
265
- ) -> McfResult {
238
+ fn check_operand<'tcx>(tcx: TyCtxt<'tcx>, operand: &Operand<'tcx>, span: Span, body: &Body<'tcx>) -> McfResult {
266
239
match operand {
267
240
Operand::Move(place) | Operand::Copy(place) => check_place(tcx, *place, span, body),
268
241
Operand::Constant(c) => match c.check_static_ptr(tcx) {
@@ -272,12 +245,7 @@ fn check_operand<'tcx>(
272
245
}
273
246
}
274
247
275
- fn check_place<'tcx>(
276
- tcx: TyCtxt<'tcx>,
277
- place: Place<'tcx>,
278
- span: Span,
279
- body: &Body<'tcx>,
280
- ) -> McfResult {
248
+ fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &Body<'tcx>) -> McfResult {
281
249
let mut cursor = place.projection.as_ref();
282
250
while let [ref proj_base @ .., elem] = *cursor {
283
251
cursor = proj_base;
@@ -290,12 +258,12 @@ fn check_place<'tcx>(
290
258
return Err((span, "accessing union fields is unstable".into()));
291
259
}
292
260
}
293
- }
261
+ },
294
262
ProjectionElem::ConstantIndex { .. }
295
263
| ProjectionElem::Downcast(..)
296
264
| ProjectionElem::Subslice { .. }
297
265
| ProjectionElem::Deref
298
- | ProjectionElem::Index(_) => {}
266
+ | ProjectionElem::Index(_) => {},
299
267
}
300
268
}
301
269
@@ -321,16 +289,18 @@ fn check_terminator<'a, 'tcx>(
321
289
TerminatorKind::DropAndReplace { place, value, .. } => {
322
290
check_place(tcx, *place, span, body)?;
323
291
check_operand(tcx, value, span, body)
324
- }
292
+ },
325
293
326
- TerminatorKind::SwitchInt { discr, switch_ty: _, targets: _ } => {
327
- check_operand(tcx, discr, span, body)
328
- }
294
+ TerminatorKind::SwitchInt {
295
+ discr,
296
+ switch_ty: _,
297
+ targets: _,
298
+ } => check_operand(tcx, discr, span, body),
329
299
330
300
TerminatorKind::Abort => Err((span, "abort is not stable in const fn".into())),
331
301
TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => {
332
302
Err((span, "const fn generators are unstable".into()))
333
- }
303
+ },
334
304
335
305
TerminatorKind::Call {
336
306
func,
@@ -375,15 +345,17 @@ fn check_terminator<'a, 'tcx>(
375
345
} else {
376
346
Err((span, "can only call other const fns within const fn".into()))
377
347
}
378
- }
348
+ },
379
349
380
- TerminatorKind::Assert { cond, expected: _, msg: _, target: _, cleanup: _ } => {
381
- check_operand(tcx, cond, span, body)
382
- }
350
+ TerminatorKind::Assert {
351
+ cond,
352
+ expected: _,
353
+ msg: _,
354
+ target: _,
355
+ cleanup: _,
356
+ } => check_operand(tcx, cond, span, body),
383
357
384
- TerminatorKind::InlineAsm { .. } => {
385
- Err((span, "cannot use inline assembly in const fn".into()))
386
- }
358
+ TerminatorKind::InlineAsm { .. } => Err((span, "cannot use inline assembly in const fn".into())),
387
359
}
388
360
}
389
361
0 commit comments