@@ -3,22 +3,14 @@ use rustc_hir::def_id::DefId;
33use rustc_middle:: mir:: * ;
44use rustc_middle:: ty:: subst:: GenericArgKind ;
55use rustc_middle:: ty:: { self , adjustment:: PointerCast , Ty , TyCtxt } ;
6- use rustc_span:: symbol:: { sym, Symbol } ;
6+ use rustc_span:: symbol:: { sym} ;
77use rustc_span:: Span ;
88use rustc_target:: spec:: abi:: Abi :: RustIntrinsic ;
99use std:: borrow:: Cow ;
1010
1111type McfResult = Result < ( ) , ( Span , Cow < ' static , str > ) > ;
1212
1313pub 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 rustc_mir:: 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-
2214 let mut current = def_id;
2315 loop {
2416 let predicates = tcx. predicates_of ( current) ;
@@ -40,19 +32,12 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
4032 ty:: PredicateAtom :: Subtype ( _) => {
4133 panic ! ( "subtype predicate on function: {:#?}" , predicate)
4234 }
43- ty:: PredicateAtom :: Trait ( pred, constness ) => {
35+ ty:: PredicateAtom :: Trait ( pred, _ ) => {
4436 if Some ( pred. def_id ( ) ) == tcx. lang_items ( ) . sized_trait ( ) {
4537 continue ;
4638 }
4739 match pred. self_ty ( ) . kind ( ) {
4840 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-
5641 let generics = tcx. generics_of ( current) ;
5742 let def = generics. type_param ( p, tcx) ;
5843 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>) -
7762 }
7863
7964 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 ) ?;
8166 }
8267 // impl trait is gone in MIR, so check the return type manually
8368 check_ty (
8469 tcx,
8570 tcx. fn_sig ( def_id) . output ( ) . skip_binder ( ) ,
8671 body. local_decls . iter ( ) . next ( ) . unwrap ( ) . source_info . span ,
87- def_id,
8872 ) ?;
8973
9074 for bb in body. basic_blocks ( ) {
91- check_terminator ( tcx, body, def_id , bb. terminator ( ) ) ?;
75+ check_terminator ( tcx, body, bb. terminator ( ) ) ?;
9276 for stmt in & bb. statements {
9377 check_statement ( tcx, body, def_id, stmt) ?;
9478 }
9579 }
9680 Ok ( ( ) )
9781}
9882
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 {
10084 for arg in ty. walk ( ) {
10185 let ty = match arg. unpack ( ) {
10286 GenericArgKind :: Type ( ty) => ty,
@@ -108,15 +92,11 @@ fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, fn_def_id: DefId) -> Mc
10892
10993 match ty. kind ( ) {
11094 ty:: Ref ( _, _, hir:: Mutability :: Mut ) => {
111- if !feature_allowed ( tcx, fn_def_id, sym:: const_mut_refs) {
11295 return Err ( ( span, "mutable references in const fn are unstable" . into ( ) ) ) ;
113- }
11496 }
11597 ty:: Opaque ( ..) => return Err ( ( span, "`impl Trait` in const fn is unstable" . into ( ) ) ) ,
11698 ty:: FnPtr ( ..) => {
117- if !tcx. const_fn_is_allowed_fn_ptr ( fn_def_id) {
11899 return Err ( ( span, "function pointers in const fn are unstable" . into ( ) ) ) ;
119- }
120100 }
121101 ty:: Dynamic ( preds, _) => {
122102 for pred in preds. iter ( ) {
@@ -161,12 +141,12 @@ fn check_rvalue(
161141 Err ( ( span, "cannot access thread local storage in const fn" . into ( ) ) )
162142 }
163143 Rvalue :: Repeat ( operand, _) | Rvalue :: Use ( operand) => {
164- check_operand ( tcx, operand, span, def_id , body)
144+ check_operand ( tcx, operand, span, body)
165145 }
166146 Rvalue :: Len ( place)
167147 | Rvalue :: Discriminant ( place)
168148 | 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) ,
170150 Rvalue :: Cast ( CastKind :: Misc , operand, cast_ty) => {
171151 use rustc_middle:: ty:: cast:: CastTy ;
172152 let cast_in = CastTy :: from_ty ( operand. ty ( body, tcx) ) . expect ( "bad input type for cast" ) ;
@@ -175,14 +155,14 @@ fn check_rvalue(
175155 ( CastTy :: Ptr ( _) | CastTy :: FnPtr , CastTy :: Int ( _) ) => {
176156 Err ( ( span, "casting pointers to ints is unstable in const fn" . into ( ) ) )
177157 }
178- _ => check_operand ( tcx, operand, span, def_id , body) ,
158+ _ => check_operand ( tcx, operand, span, body) ,
179159 }
180160 }
181161 Rvalue :: Cast (
182162 CastKind :: Pointer ( PointerCast :: MutToConstPointer | PointerCast :: ArrayToPointer ) ,
183163 operand,
184164 _,
185- ) => check_operand ( tcx, operand, span, def_id , body) ,
165+ ) => check_operand ( tcx, operand, span, body) ,
186166 Rvalue :: Cast (
187167 CastKind :: Pointer (
188168 PointerCast :: UnsafeFnPointer
@@ -204,7 +184,7 @@ fn check_rvalue(
204184 } ;
205185 let unsized_ty = tcx. struct_tail_erasing_lifetimes ( pointee_ty, tcx. param_env ( def_id) ) ;
206186 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) ?;
208188 // Casting/coercing things to slices is fine.
209189 Ok ( ( ) )
210190 } else {
@@ -214,8 +194,8 @@ fn check_rvalue(
214194 }
215195 // binops are fine on integers
216196 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) ?;
219199 let ty = lhs. ty ( body, tcx) ;
220200 if ty. is_integral ( ) || ty. is_bool ( ) || ty. is_char ( ) {
221201 Ok ( ( ) )
@@ -230,14 +210,14 @@ fn check_rvalue(
230210 Rvalue :: UnaryOp ( _, operand) => {
231211 let ty = operand. ty ( body, tcx) ;
232212 if ty. is_integral ( ) || ty. is_bool ( ) {
233- check_operand ( tcx, operand, span, def_id , body)
213+ check_operand ( tcx, operand, span, body)
234214 } else {
235215 Err ( ( span, "only int and `bool` operations are stable in const fn" . into ( ) ) )
236216 }
237217 }
238218 Rvalue :: Aggregate ( _, operands) => {
239219 for operand in operands {
240- check_operand ( tcx, operand, span, def_id , body) ?;
220+ check_operand ( tcx, operand, span, body) ?;
241221 }
242222 Ok ( ( ) )
243223 }
@@ -253,15 +233,15 @@ fn check_statement(
253233 let span = statement. source_info . span ;
254234 match & statement. kind {
255235 StatementKind :: Assign ( box ( place, rval) ) => {
256- check_place ( tcx, * place, span, def_id , body) ?;
236+ check_place ( tcx, * place, span, body) ?;
257237 check_rvalue ( tcx, body, def_id, rval, span)
258238 }
259239
260- StatementKind :: FakeRead ( _, place) => check_place ( tcx, * * place, span, def_id , body) ,
240+ StatementKind :: FakeRead ( _, place) => check_place ( tcx, * * place, span, body) ,
261241
262242 // just an assignment
263243 StatementKind :: SetDiscriminant { place, .. } => {
264- check_place ( tcx, * * place, span, def_id , body)
244+ check_place ( tcx, * * place, span, body)
265245 }
266246
267247 StatementKind :: LlvmInlineAsm { .. } => {
@@ -282,11 +262,10 @@ fn check_operand(
282262 tcx : TyCtxt < ' tcx > ,
283263 operand : & Operand < ' tcx > ,
284264 span : Span ,
285- def_id : DefId ,
286265 body : & Body < ' tcx > ,
287266) -> McfResult {
288267 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) ,
290269 Operand :: Constant ( c) => match c. check_static_ptr ( tcx) {
291270 Some ( _) => Err ( ( span, "cannot access `static` items in const fn" . into ( ) ) ) ,
292271 None => Ok ( ( ) ) ,
@@ -298,7 +277,6 @@ fn check_place(
298277 tcx : TyCtxt < ' tcx > ,
299278 place : Place < ' tcx > ,
300279 span : Span ,
301- def_id : DefId ,
302280 body : & Body < ' tcx > ,
303281) -> McfResult {
304282 let mut cursor = place. projection . as_ref ( ) ;
@@ -310,9 +288,7 @@ fn check_place(
310288 if let Some ( def) = base_ty. ty_adt_def ( ) {
311289 // No union field accesses in `const fn`
312290 if def. is_union ( ) {
313- if !feature_allowed ( tcx, def_id, sym:: const_fn_union) {
314291 return Err ( ( span, "accessing union fields is unstable" . into ( ) ) ) ;
315- }
316292 }
317293 }
318294 }
@@ -327,48 +303,9 @@ fn check_place(
327303 Ok ( ( ) )
328304}
329305
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- rustc_mir:: transform:: 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- rustc_mir:: transform:: check_consts:: allow_internal_unstable ( tcx, def_id, feature_gate)
366- }
367-
368306fn check_terminator (
369307 tcx : TyCtxt < ' tcx > ,
370308 body : & ' a Body < ' tcx > ,
371- def_id : DefId ,
372309 terminator : & Terminator < ' tcx > ,
373310) -> McfResult {
374311 let span = terminator. source_info . span ;
@@ -380,14 +317,14 @@ fn check_terminator(
380317 | TerminatorKind :: Resume
381318 | TerminatorKind :: Unreachable => Ok ( ( ) ) ,
382319
383- TerminatorKind :: Drop { place, .. } => check_place ( tcx, * place, span, def_id , body) ,
320+ TerminatorKind :: Drop { place, .. } => check_place ( tcx, * place, span, body) ,
384321 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)
387324 }
388325
389326 TerminatorKind :: SwitchInt { discr, switch_ty : _, values : _, targets : _ } => {
390- check_operand ( tcx, discr, span, def_id , body)
327+ check_operand ( tcx, discr, span, body)
391328 }
392329
393330 TerminatorKind :: Abort => Err ( ( span, "abort is not stable in const fn" . into ( ) ) ) ,
@@ -405,15 +342,7 @@ fn check_terminator(
405342 } => {
406343 let fn_ty = func. ty ( body, tcx) ;
407344 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.
410345 if !rustc_mir:: const_eval:: is_min_const_fn ( tcx, fn_def_id)
411- && !rustc_mir:: 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 )
417346 {
418347 return Err ( (
419348 span,
@@ -432,18 +361,17 @@ fn check_terminator(
432361 // transmutes in const fn before we add more hacks to this.
433362 if tcx. fn_sig ( fn_def_id) . abi ( ) == RustIntrinsic
434363 && tcx. item_name ( fn_def_id) == sym:: transmute
435- && !feature_allowed ( tcx, def_id, sym:: const_fn_transmute)
436364 {
437365 return Err ( (
438366 span,
439367 "can only call `transmute` from const items, not `const fn`" . into ( ) ,
440368 ) ) ;
441369 }
442370
443- check_operand ( tcx, func, span, fn_def_id , body) ?;
371+ check_operand ( tcx, func, span, body) ?;
444372
445373 for arg in args {
446- check_operand ( tcx, arg, span, fn_def_id , body) ?;
374+ check_operand ( tcx, arg, span, body) ?;
447375 }
448376 Ok ( ( ) )
449377 } else {
@@ -452,7 +380,7 @@ fn check_terminator(
452380 }
453381
454382 TerminatorKind :: Assert { cond, expected : _, msg : _, target : _, cleanup : _ } => {
455- check_operand ( tcx, cond, span, def_id , body)
383+ check_operand ( tcx, cond, span, body)
456384 }
457385
458386 TerminatorKind :: InlineAsm { .. } => {
0 commit comments