@@ -3,22 +3,14 @@ use rustc_hir::def_id::DefId;
3
3
use rustc_middle:: mir:: * ;
4
4
use rustc_middle:: ty:: subst:: GenericArgKind ;
5
5
use rustc_middle:: ty:: { self , adjustment:: PointerCast , Ty , TyCtxt } ;
6
- use rustc_span:: symbol:: { sym, Symbol } ;
6
+ use rustc_span:: symbol:: { sym} ;
7
7
use rustc_span:: Span ;
8
8
use rustc_target:: spec:: abi:: Abi :: RustIntrinsic ;
9
9
use std:: borrow:: Cow ;
10
10
11
11
type McfResult = Result < ( ) , ( Span , Cow < ' static , str > ) > ;
12
12
13
13
pub fn is_min_const_fn ( tcx : TyCtxt < ' tcx > , def_id : DefId , body : & ' a Body < ' tcx > ) -> McfResult {
14
- // Prevent const trait methods from being annotated as `stable`.
15
- if tcx. features ( ) . staged_api {
16
- let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id. expect_local ( ) ) ;
17
- if crate :: const_eval:: is_parent_const_impl_raw ( tcx, hir_id) {
18
- return Err ( ( body. span , "trait methods cannot be stable const fn" . into ( ) ) ) ;
19
- }
20
- }
21
-
22
14
let mut current = def_id;
23
15
loop {
24
16
let predicates = tcx. predicates_of ( current) ;
@@ -32,27 +24,20 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
32
24
| ty:: PredicateAtom :: ConstEquate ( ..)
33
25
| ty:: PredicateAtom :: TypeWellFormedFromEnv ( ..) => continue ,
34
26
ty:: PredicateAtom :: ObjectSafe ( _) => {
35
- bug ! ( "object safe predicate on function: {:#?}" , predicate)
27
+ panic ! ( "object safe predicate on function: {:#?}" , predicate)
36
28
}
37
29
ty:: PredicateAtom :: ClosureKind ( ..) => {
38
- bug ! ( "closure kind predicate on function: {:#?}" , predicate)
30
+ panic ! ( "closure kind predicate on function: {:#?}" , predicate)
39
31
}
40
32
ty:: PredicateAtom :: Subtype ( _) => {
41
- bug ! ( "subtype predicate on function: {:#?}" , predicate)
33
+ panic ! ( "subtype predicate on function: {:#?}" , predicate)
42
34
}
43
- ty:: PredicateAtom :: Trait ( pred, constness ) => {
35
+ ty:: PredicateAtom :: Trait ( pred, _ ) => {
44
36
if Some ( pred. def_id ( ) ) == tcx. lang_items ( ) . sized_trait ( ) {
45
37
continue ;
46
38
}
47
39
match pred. self_ty ( ) . kind ( ) {
48
40
ty:: Param ( ref p) => {
49
- // Allow `T: ?const Trait`
50
- if constness == hir:: Constness :: NotConst
51
- && feature_allowed ( tcx, def_id, sym:: const_trait_bound_opt_out)
52
- {
53
- continue ;
54
- }
55
-
56
41
let generics = tcx. generics_of ( current) ;
57
42
let def = generics. type_param ( p, tcx) ;
58
43
let span = tcx. def_span ( def. def_id ) ;
@@ -77,26 +62,25 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
77
62
}
78
63
79
64
for local in & body. local_decls {
80
- check_ty ( tcx, local. ty , local. source_info . span , def_id ) ?;
65
+ check_ty ( tcx, local. ty , local. source_info . span ) ?;
81
66
}
82
67
// impl trait is gone in MIR, so check the return type manually
83
68
check_ty (
84
69
tcx,
85
70
tcx. fn_sig ( def_id) . output ( ) . skip_binder ( ) ,
86
71
body. local_decls . iter ( ) . next ( ) . unwrap ( ) . source_info . span ,
87
- def_id,
88
72
) ?;
89
73
90
74
for bb in body. basic_blocks ( ) {
91
- check_terminator ( tcx, body, def_id , bb. terminator ( ) ) ?;
75
+ check_terminator ( tcx, body, bb. terminator ( ) ) ?;
92
76
for stmt in & bb. statements {
93
77
check_statement ( tcx, body, def_id, stmt) ?;
94
78
}
95
79
}
96
80
Ok ( ( ) )
97
81
}
98
82
99
- fn check_ty ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > , span : Span , fn_def_id : DefId ) -> McfResult {
83
+ fn check_ty ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > , span : Span ) -> McfResult {
100
84
for arg in ty. walk ( ) {
101
85
let ty = match arg. unpack ( ) {
102
86
GenericArgKind :: Type ( ty) => ty,
@@ -108,15 +92,11 @@ fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, fn_def_id: DefId) -> Mc
108
92
109
93
match ty. kind ( ) {
110
94
ty:: Ref ( _, _, hir:: Mutability :: Mut ) => {
111
- if !feature_allowed ( tcx, fn_def_id, sym:: const_mut_refs) {
112
95
return Err ( ( span, "mutable references in const fn are unstable" . into ( ) ) ) ;
113
- }
114
96
}
115
97
ty:: Opaque ( ..) => return Err ( ( span, "`impl Trait` in const fn is unstable" . into ( ) ) ) ,
116
98
ty:: FnPtr ( ..) => {
117
- if !tcx. const_fn_is_allowed_fn_ptr ( fn_def_id) {
118
99
return Err ( ( span, "function pointers in const fn are unstable" . into ( ) ) ) ;
119
- }
120
100
}
121
101
ty:: Dynamic ( preds, _) => {
122
102
for pred in preds. iter ( ) {
@@ -161,12 +141,12 @@ fn check_rvalue(
161
141
Err ( ( span, "cannot access thread local storage in const fn" . into ( ) ) )
162
142
}
163
143
Rvalue :: Repeat ( operand, _) | Rvalue :: Use ( operand) => {
164
- check_operand ( tcx, operand, span, def_id , body)
144
+ check_operand ( tcx, operand, span, body)
165
145
}
166
146
Rvalue :: Len ( place)
167
147
| Rvalue :: Discriminant ( place)
168
148
| Rvalue :: Ref ( _, _, place)
169
- | Rvalue :: AddressOf ( _, place) => check_place ( tcx, * place, span, def_id , body) ,
149
+ | Rvalue :: AddressOf ( _, place) => check_place ( tcx, * place, span, body) ,
170
150
Rvalue :: Cast ( CastKind :: Misc , operand, cast_ty) => {
171
151
use rustc_middle:: ty:: cast:: CastTy ;
172
152
let cast_in = CastTy :: from_ty ( operand. ty ( body, tcx) ) . expect ( "bad input type for cast" ) ;
@@ -175,14 +155,14 @@ fn check_rvalue(
175
155
( CastTy :: Ptr ( _) | CastTy :: FnPtr , CastTy :: Int ( _) ) => {
176
156
Err ( ( span, "casting pointers to ints is unstable in const fn" . into ( ) ) )
177
157
}
178
- _ => check_operand ( tcx, operand, span, def_id , body) ,
158
+ _ => check_operand ( tcx, operand, span, body) ,
179
159
}
180
160
}
181
161
Rvalue :: Cast (
182
162
CastKind :: Pointer ( PointerCast :: MutToConstPointer | PointerCast :: ArrayToPointer ) ,
183
163
operand,
184
164
_,
185
- ) => check_operand ( tcx, operand, span, def_id , body) ,
165
+ ) => check_operand ( tcx, operand, span, body) ,
186
166
Rvalue :: Cast (
187
167
CastKind :: Pointer (
188
168
PointerCast :: UnsafeFnPointer
@@ -204,7 +184,7 @@ fn check_rvalue(
204
184
} ;
205
185
let unsized_ty = tcx. struct_tail_erasing_lifetimes ( pointee_ty, tcx. param_env ( def_id) ) ;
206
186
if let ty:: Slice ( _) | ty:: Str = unsized_ty. kind ( ) {
207
- check_operand ( tcx, op, span, def_id , body) ?;
187
+ check_operand ( tcx, op, span, body) ?;
208
188
// Casting/coercing things to slices is fine.
209
189
Ok ( ( ) )
210
190
} else {
@@ -214,8 +194,8 @@ fn check_rvalue(
214
194
}
215
195
// binops are fine on integers
216
196
Rvalue :: BinaryOp ( _, lhs, rhs) | Rvalue :: CheckedBinaryOp ( _, lhs, rhs) => {
217
- check_operand ( tcx, lhs, span, def_id , body) ?;
218
- check_operand ( tcx, rhs, span, def_id , body) ?;
197
+ check_operand ( tcx, lhs, span, body) ?;
198
+ check_operand ( tcx, rhs, span, body) ?;
219
199
let ty = lhs. ty ( body, tcx) ;
220
200
if ty. is_integral ( ) || ty. is_bool ( ) || ty. is_char ( ) {
221
201
Ok ( ( ) )
@@ -230,14 +210,14 @@ fn check_rvalue(
230
210
Rvalue :: UnaryOp ( _, operand) => {
231
211
let ty = operand. ty ( body, tcx) ;
232
212
if ty. is_integral ( ) || ty. is_bool ( ) {
233
- check_operand ( tcx, operand, span, def_id , body)
213
+ check_operand ( tcx, operand, span, body)
234
214
} else {
235
215
Err ( ( span, "only int and `bool` operations are stable in const fn" . into ( ) ) )
236
216
}
237
217
}
238
218
Rvalue :: Aggregate ( _, operands) => {
239
219
for operand in operands {
240
- check_operand ( tcx, operand, span, def_id , body) ?;
220
+ check_operand ( tcx, operand, span, body) ?;
241
221
}
242
222
Ok ( ( ) )
243
223
}
@@ -253,15 +233,15 @@ fn check_statement(
253
233
let span = statement. source_info . span ;
254
234
match & statement. kind {
255
235
StatementKind :: Assign ( box ( place, rval) ) => {
256
- check_place ( tcx, * place, span, def_id , body) ?;
236
+ check_place ( tcx, * place, span, body) ?;
257
237
check_rvalue ( tcx, body, def_id, rval, span)
258
238
}
259
239
260
- StatementKind :: FakeRead ( _, place) => check_place ( tcx, * * place, span, def_id , body) ,
240
+ StatementKind :: FakeRead ( _, place) => check_place ( tcx, * * place, span, body) ,
261
241
262
242
// just an assignment
263
243
StatementKind :: SetDiscriminant { place, .. } => {
264
- check_place ( tcx, * * place, span, def_id , body)
244
+ check_place ( tcx, * * place, span, body)
265
245
}
266
246
267
247
StatementKind :: LlvmInlineAsm { .. } => {
@@ -282,11 +262,10 @@ fn check_operand(
282
262
tcx : TyCtxt < ' tcx > ,
283
263
operand : & Operand < ' tcx > ,
284
264
span : Span ,
285
- def_id : DefId ,
286
265
body : & Body < ' tcx > ,
287
266
) -> McfResult {
288
267
match operand {
289
- Operand :: Move ( place) | Operand :: Copy ( place) => check_place ( tcx, * place, span, def_id , body) ,
268
+ Operand :: Move ( place) | Operand :: Copy ( place) => check_place ( tcx, * place, span, body) ,
290
269
Operand :: Constant ( c) => match c. check_static_ptr ( tcx) {
291
270
Some ( _) => Err ( ( span, "cannot access `static` items in const fn" . into ( ) ) ) ,
292
271
None => Ok ( ( ) ) ,
@@ -298,7 +277,6 @@ fn check_place(
298
277
tcx : TyCtxt < ' tcx > ,
299
278
place : Place < ' tcx > ,
300
279
span : Span ,
301
- def_id : DefId ,
302
280
body : & Body < ' tcx > ,
303
281
) -> McfResult {
304
282
let mut cursor = place. projection . as_ref ( ) ;
@@ -310,9 +288,7 @@ fn check_place(
310
288
if let Some ( def) = base_ty. ty_adt_def ( ) {
311
289
// No union field accesses in `const fn`
312
290
if def. is_union ( ) {
313
- if !feature_allowed ( tcx, def_id, sym:: const_fn_union) {
314
291
return Err ( ( span, "accessing union fields is unstable" . into ( ) ) ) ;
315
- }
316
292
}
317
293
}
318
294
}
@@ -327,48 +303,9 @@ fn check_place(
327
303
Ok ( ( ) )
328
304
}
329
305
330
- /// Returns `true` if the given feature gate is allowed within the function with the given `DefId`.
331
- fn feature_allowed ( tcx : TyCtxt < ' tcx > , def_id : DefId , feature_gate : Symbol ) -> bool {
332
- // All features require that the corresponding gate be enabled,
333
- // even if the function has `#[allow_internal_unstable(the_gate)]`.
334
- if !tcx. features ( ) . enabled ( feature_gate) {
335
- return false ;
336
- }
337
-
338
- // If this crate is not using stability attributes, or this function is not claiming to be a
339
- // stable `const fn`, that is all that is required.
340
- if !tcx. features ( ) . staged_api || tcx. has_attr ( def_id, sym:: rustc_const_unstable) {
341
- return true ;
342
- }
343
-
344
- // However, we cannot allow stable `const fn`s to use unstable features without an explicit
345
- // opt-in via `allow_internal_unstable`.
346
- super :: check_consts:: allow_internal_unstable ( tcx, def_id, feature_gate)
347
- }
348
-
349
- /// Returns `true` if the given library feature gate is allowed within the function with the given `DefId`.
350
- pub fn lib_feature_allowed ( tcx : TyCtxt < ' tcx > , def_id : DefId , feature_gate : Symbol ) -> bool {
351
- // All features require that the corresponding gate be enabled,
352
- // even if the function has `#[allow_internal_unstable(the_gate)]`.
353
- if !tcx. features ( ) . declared_lib_features . iter ( ) . any ( |& ( sym, _) | sym == feature_gate) {
354
- return false ;
355
- }
356
-
357
- // If this crate is not using stability attributes, or this function is not claiming to be a
358
- // stable `const fn`, that is all that is required.
359
- if !tcx. features ( ) . staged_api || tcx. has_attr ( def_id, sym:: rustc_const_unstable) {
360
- return true ;
361
- }
362
-
363
- // However, we cannot allow stable `const fn`s to use unstable features without an explicit
364
- // opt-in via `allow_internal_unstable`.
365
- super :: check_consts:: allow_internal_unstable ( tcx, def_id, feature_gate)
366
- }
367
-
368
306
fn check_terminator (
369
307
tcx : TyCtxt < ' tcx > ,
370
308
body : & ' a Body < ' tcx > ,
371
- def_id : DefId ,
372
309
terminator : & Terminator < ' tcx > ,
373
310
) -> McfResult {
374
311
let span = terminator. source_info . span ;
@@ -380,14 +317,14 @@ fn check_terminator(
380
317
| TerminatorKind :: Resume
381
318
| TerminatorKind :: Unreachable => Ok ( ( ) ) ,
382
319
383
- TerminatorKind :: Drop { place, .. } => check_place ( tcx, * place, span, def_id , body) ,
320
+ TerminatorKind :: Drop { place, .. } => check_place ( tcx, * place, span, body) ,
384
321
TerminatorKind :: DropAndReplace { place, value, .. } => {
385
- check_place ( tcx, * place, span, def_id , body) ?;
386
- check_operand ( tcx, value, span, def_id , body)
322
+ check_place ( tcx, * place, span, body) ?;
323
+ check_operand ( tcx, value, span, body)
387
324
}
388
325
389
326
TerminatorKind :: SwitchInt { discr, switch_ty : _, values : _, targets : _ } => {
390
- check_operand ( tcx, discr, span, def_id , body)
327
+ check_operand ( tcx, discr, span, body)
391
328
}
392
329
393
330
TerminatorKind :: Abort => Err ( ( span, "abort is not stable in const fn" . into ( ) ) ) ,
@@ -405,15 +342,7 @@ fn check_terminator(
405
342
} => {
406
343
let fn_ty = func. ty ( body, tcx) ;
407
344
if let ty:: FnDef ( fn_def_id, _) = * fn_ty. kind ( ) {
408
- // Allow unstable const if we opt in by using #[allow_internal_unstable]
409
- // on function or macro declaration.
410
- if !crate :: const_eval:: is_min_const_fn ( tcx, fn_def_id)
411
- && !crate :: const_eval:: is_unstable_const_fn ( tcx, fn_def_id)
412
- . map ( |feature| {
413
- span. allows_unstable ( feature)
414
- || lib_feature_allowed ( tcx, def_id, feature)
415
- } )
416
- . unwrap_or ( false )
345
+ if !rustc_mir:: const_eval:: is_min_const_fn ( tcx, fn_def_id)
417
346
{
418
347
return Err ( (
419
348
span,
@@ -432,18 +361,17 @@ fn check_terminator(
432
361
// transmutes in const fn before we add more hacks to this.
433
362
if tcx. fn_sig ( fn_def_id) . abi ( ) == RustIntrinsic
434
363
&& tcx. item_name ( fn_def_id) == sym:: transmute
435
- && !feature_allowed ( tcx, def_id, sym:: const_fn_transmute)
436
364
{
437
365
return Err ( (
438
366
span,
439
367
"can only call `transmute` from const items, not `const fn`" . into ( ) ,
440
368
) ) ;
441
369
}
442
370
443
- check_operand ( tcx, func, span, fn_def_id , body) ?;
371
+ check_operand ( tcx, func, span, body) ?;
444
372
445
373
for arg in args {
446
- check_operand ( tcx, arg, span, fn_def_id , body) ?;
374
+ check_operand ( tcx, arg, span, body) ?;
447
375
}
448
376
Ok ( ( ) )
449
377
} else {
@@ -452,7 +380,7 @@ fn check_terminator(
452
380
}
453
381
454
382
TerminatorKind :: Assert { cond, expected : _, msg : _, target : _, cleanup : _ } => {
455
- check_operand ( tcx, cond, span, def_id , body)
383
+ check_operand ( tcx, cond, span, body)
456
384
}
457
385
458
386
TerminatorKind :: InlineAsm { .. } => {
0 commit comments