@@ -98,6 +98,34 @@ pub trait NonConstOp: std::fmt::Debug {
98
98
}
99
99
}
100
100
101
+ #[ derive( Debug ) ]
102
+ pub struct Abort ;
103
+ impl NonConstOp for Abort {
104
+ const STOPS_CONST_CHECKING : bool = true ;
105
+
106
+ fn status_in_item ( & self , ccx : & ConstCx < ' _ , ' _ > ) -> Status {
107
+ mcf_status_in_item ( ccx)
108
+ }
109
+
110
+ fn emit_error ( & self , ccx : & ConstCx < ' _ , ' _ > , span : Span ) {
111
+ mcf_emit_error ( ccx, span, "abort is not stable in const fn" )
112
+ }
113
+ }
114
+
115
+ #[ derive( Debug ) ]
116
+ pub struct NonPrimitiveOp ;
117
+ impl NonConstOp for NonPrimitiveOp {
118
+ const STOPS_CONST_CHECKING : bool = true ;
119
+
120
+ fn status_in_item ( & self , ccx : & ConstCx < ' _ , ' _ > ) -> Status {
121
+ mcf_status_in_item ( ccx)
122
+ }
123
+
124
+ fn emit_error ( & self , ccx : & ConstCx < ' _ , ' _ > , span : Span ) {
125
+ mcf_emit_error ( ccx, span, "only int, `bool` and `char` operations are stable in const fn" )
126
+ }
127
+ }
128
+
101
129
/// A function call where the callee is a pointer.
102
130
#[ derive( Debug ) ]
103
131
pub struct FnCallIndirect ;
@@ -130,7 +158,8 @@ impl NonConstOp for FnCallNonConst {
130
158
///
131
159
/// Contains the name of the feature that would allow the use of this function.
132
160
#[ derive( Debug ) ]
133
- pub struct FnCallUnstable ( pub DefId , pub Symbol ) ;
161
+ pub struct FnCallUnstable ( pub DefId , pub Option < Symbol > ) ;
162
+
134
163
impl NonConstOp for FnCallUnstable {
135
164
fn emit_error ( & self , ccx : & ConstCx < ' _ , ' _ > , span : Span ) {
136
165
let FnCallUnstable ( def_id, feature) = * self ;
@@ -139,13 +168,51 @@ impl NonConstOp for FnCallUnstable {
139
168
span,
140
169
& format ! ( "`{}` is not yet stable as a const fn" , ccx. tcx. def_path_str( def_id) ) ,
141
170
) ;
142
- if nightly_options:: is_nightly_build ( ) {
143
- err. help ( & format ! ( "add `#![feature({})]` to the crate attributes to enable" , feature) ) ;
171
+
172
+ if ccx. is_const_stable_const_fn ( ) {
173
+ err. help ( "Const-stable functions can only call other const-stable functions" ) ;
174
+ } else if nightly_options:: is_nightly_build ( ) {
175
+ if let Some ( feature) = feature {
176
+ err. help ( & format ! (
177
+ "add `#![feature({})]` to the crate attributes to enable" ,
178
+ feature
179
+ ) ) ;
180
+ }
144
181
}
145
182
err. emit ( ) ;
146
183
}
147
184
}
148
185
186
+ #[ derive( Debug ) ]
187
+ pub struct FnPtrCast ;
188
+ impl NonConstOp for FnPtrCast {
189
+ const STOPS_CONST_CHECKING : bool = true ;
190
+
191
+ fn status_in_item ( & self , ccx : & ConstCx < ' _ , ' _ > ) -> Status {
192
+ mcf_status_in_item ( ccx)
193
+ }
194
+
195
+ fn emit_error ( & self , ccx : & ConstCx < ' _ , ' _ > , span : Span ) {
196
+ mcf_emit_error ( ccx, span, "function pointer casts are not allowed in const fn" ) ;
197
+ }
198
+ }
199
+
200
+ #[ derive( Debug ) ]
201
+ pub struct Generator ;
202
+ impl NonConstOp for Generator {
203
+ const STOPS_CONST_CHECKING : bool = true ;
204
+
205
+ fn status_in_item ( & self , ccx : & ConstCx < ' _ , ' _ > ) -> Status {
206
+ // FIXME: This means generator-only MIR is only forbidden in const fn. This is for
207
+ // compatibility with the old code. Such MIR should be forbidden everywhere.
208
+ mcf_status_in_item ( ccx)
209
+ }
210
+
211
+ fn emit_error ( & self , ccx : & ConstCx < ' _ , ' _ > , span : Span ) {
212
+ mcf_emit_error ( ccx, span, "const fn generators are unstable" ) ;
213
+ }
214
+ }
215
+
149
216
#[ derive( Debug ) ]
150
217
pub struct HeapAllocation ;
151
218
impl NonConstOp for HeapAllocation {
@@ -408,6 +475,24 @@ impl NonConstOp for ThreadLocalAccess {
408
475
}
409
476
}
410
477
478
+ #[ derive( Debug ) ]
479
+ pub struct Transmute ;
480
+ impl NonConstOp for Transmute {
481
+ const STOPS_CONST_CHECKING : bool = true ;
482
+
483
+ fn status_in_item ( & self , ccx : & ConstCx < ' _ , ' _ > ) -> Status {
484
+ if ccx. const_kind ( ) != hir:: ConstContext :: ConstFn {
485
+ Status :: Allowed
486
+ } else {
487
+ Status :: Unstable ( sym:: const_fn_transmute)
488
+ }
489
+ }
490
+
491
+ fn emit_error ( & self , ccx : & ConstCx < ' _ , ' _ > , span : Span ) {
492
+ mcf_emit_error ( ccx, span, "can only call `transmute` from const items, not `const fn`" ) ;
493
+ }
494
+ }
495
+
411
496
#[ derive( Debug ) ]
412
497
pub struct UnionAccess ;
413
498
impl NonConstOp for UnionAccess {
@@ -430,3 +515,135 @@ impl NonConstOp for UnionAccess {
430
515
. emit ( ) ;
431
516
}
432
517
}
518
+
519
+ /// See [#64992].
520
+ ///
521
+ /// [#64992]: https://github.com/rust-lang/rust/issues/64992
522
+ #[ derive( Debug ) ]
523
+ pub struct UnsizingCast ;
524
+ impl NonConstOp for UnsizingCast {
525
+ fn status_in_item ( & self , ccx : & ConstCx < ' _ , ' _ > ) -> Status {
526
+ if ccx. const_kind ( ) != hir:: ConstContext :: ConstFn {
527
+ Status :: Allowed
528
+ } else {
529
+ Status :: Unstable ( sym:: const_fn_transmute)
530
+ }
531
+ }
532
+
533
+ fn emit_error ( & self , ccx : & ConstCx < ' _ , ' _ > , span : Span ) {
534
+ mcf_emit_error (
535
+ ccx,
536
+ span,
537
+ "unsizing casts to types besides slices are not allowed in const fn" ,
538
+ ) ;
539
+ }
540
+ }
541
+
542
+ pub mod ty {
543
+ use super :: * ;
544
+
545
+ #[ derive( Debug ) ]
546
+ pub struct MutRef ;
547
+ impl NonConstOp for MutRef {
548
+ const STOPS_CONST_CHECKING : bool = true ;
549
+
550
+ fn status_in_item ( & self , _ccx : & ConstCx < ' _ , ' _ > ) -> Status {
551
+ Status :: Unstable ( sym:: const_mut_refs)
552
+ }
553
+
554
+ fn emit_error ( & self , ccx : & ConstCx < ' _ , ' _ > , span : Span ) {
555
+ mcf_emit_error ( ccx, span, "mutable references in const fn are unstable" ) ;
556
+ }
557
+ }
558
+
559
+ #[ derive( Debug ) ]
560
+ pub struct FnPtr ;
561
+ impl NonConstOp for FnPtr {
562
+ const STOPS_CONST_CHECKING : bool = true ;
563
+
564
+ fn status_in_item ( & self , ccx : & ConstCx < ' _ , ' _ > ) -> Status {
565
+ // FIXME: This attribute a hack to allow the specialization of the `futures` API. See
566
+ // #59739. We should have a proper feature gate for this.
567
+ if ccx. tcx . has_attr ( ccx. def_id . to_def_id ( ) , sym:: rustc_allow_const_fn_ptr) {
568
+ Status :: Allowed
569
+ } else {
570
+ mcf_status_in_item ( ccx)
571
+ }
572
+ }
573
+
574
+ fn emit_error ( & self , ccx : & ConstCx < ' _ , ' _ > , span : Span ) {
575
+ mcf_emit_error ( ccx, span, "function pointers in const fn are unstable" ) ;
576
+ }
577
+ }
578
+
579
+ #[ derive( Debug ) ]
580
+ pub struct ImplTrait ;
581
+ impl NonConstOp for ImplTrait {
582
+ const STOPS_CONST_CHECKING : bool = true ;
583
+
584
+ fn status_in_item ( & self , ccx : & ConstCx < ' _ , ' _ > ) -> Status {
585
+ mcf_status_in_item ( ccx)
586
+ }
587
+
588
+ fn emit_error ( & self , ccx : & ConstCx < ' _ , ' _ > , span : Span ) {
589
+ mcf_emit_error ( ccx, span, "`impl Trait` in const fn is unstable" ) ;
590
+ }
591
+ }
592
+
593
+ #[ derive( Debug ) ]
594
+ pub struct TraitBound ;
595
+ impl NonConstOp for TraitBound {
596
+ const STOPS_CONST_CHECKING : bool = true ;
597
+
598
+ fn status_in_item ( & self , ccx : & ConstCx < ' _ , ' _ > ) -> Status {
599
+ mcf_status_in_item ( ccx)
600
+ }
601
+
602
+ fn emit_error ( & self , ccx : & ConstCx < ' _ , ' _ > , span : Span ) {
603
+ mcf_emit_error (
604
+ ccx,
605
+ span,
606
+ "trait bounds other than `Sized` on const fn parameters are unstable" ,
607
+ ) ;
608
+ }
609
+ }
610
+
611
+ /// A trait bound with the `?const Trait` opt-out
612
+ #[ derive( Debug ) ]
613
+ pub struct TraitBoundNotConst ;
614
+ impl NonConstOp for TraitBoundNotConst {
615
+ const STOPS_CONST_CHECKING : bool = true ;
616
+
617
+ fn status_in_item ( & self , _: & ConstCx < ' _ , ' _ > ) -> Status {
618
+ Status :: Unstable ( sym:: const_trait_bound_opt_out)
619
+ }
620
+
621
+ fn emit_error ( & self , ccx : & ConstCx < ' _ , ' _ > , span : Span ) {
622
+ feature_err (
623
+ & ccx. tcx . sess . parse_sess ,
624
+ sym:: const_trait_bound_opt_out,
625
+ span,
626
+ "`?const Trait` syntax is unstable" ,
627
+ )
628
+ . emit ( )
629
+ }
630
+ }
631
+ }
632
+
633
+ fn mcf_status_in_item ( ccx : & ConstCx < ' _ , ' _ > ) -> Status {
634
+ if ccx. const_kind ( ) != hir:: ConstContext :: ConstFn {
635
+ Status :: Allowed
636
+ } else {
637
+ Status :: Unstable ( sym:: const_fn)
638
+ }
639
+ }
640
+
641
+ fn mcf_emit_error ( ccx : & ConstCx < ' _ , ' _ > , span : Span , msg : & str ) {
642
+ struct_span_err ! ( ccx. tcx. sess, span, E0723 , "{}" , msg)
643
+ . note (
644
+ "see issue #57563 <https://github.com/rust-lang/rust/issues/57563> \
645
+ for more information",
646
+ )
647
+ . help ( "add `#![feature(const_fn)]` to the crate attributes to enable" )
648
+ . emit ( ) ;
649
+ }
0 commit comments