1
1
//! Concrete error types for all operations which may be invalid in a certain const context.
2
2
3
- use rustc_errors:: struct_span_err;
3
+ use rustc_errors:: { struct_span_err, Applicability } ;
4
4
use rustc_hir as hir;
5
5
use rustc_hir:: def_id:: DefId ;
6
6
use rustc_session:: config:: nightly_options;
@@ -16,7 +16,29 @@ pub fn non_const<O: NonConstOp>(ccx: &ConstCx<'_, '_>, op: O, span: Span) {
16
16
17
17
let gate = match op. status_in_item ( ccx) {
18
18
Status :: Allowed => return ,
19
- Status :: Unstable ( gate) if ccx. tcx . features ( ) . enabled ( gate) => return ,
19
+
20
+ Status :: Unstable ( gate) if ccx. tcx . features ( ) . enabled ( gate) => {
21
+ let unstable_in_stable = ccx. const_kind ( ) == hir:: ConstContext :: ConstFn
22
+ && ccx. tcx . features ( ) . enabled ( sym:: staged_api)
23
+ && !ccx. tcx . has_attr ( ccx. def_id . to_def_id ( ) , sym:: rustc_const_unstable)
24
+ && !super :: allow_internal_unstable ( ccx. tcx , ccx. def_id . to_def_id ( ) , gate) ;
25
+
26
+ if unstable_in_stable {
27
+ ccx. tcx . sess
28
+ . struct_span_err ( span, & format ! ( "`#[feature({})]` cannot be depended on in a const-stable function" , gate. as_str( ) ) )
29
+ . span_suggestion (
30
+ ccx. body . span ,
31
+ "if it is not part of the public API, make this function unstably const" ,
32
+ concat ! ( r#"#[rustc_const_unstable(feature = "...", issue = "...")]"# , '\n' ) . to_owned ( ) ,
33
+ Applicability :: HasPlaceholders ,
34
+ )
35
+ . help ( "otherwise `#[allow_internal_unstable]` can be used to bypass stability checks" )
36
+ . emit ( ) ;
37
+ }
38
+
39
+ return ;
40
+ }
41
+
20
42
Status :: Unstable ( gate) => Some ( gate) ,
21
43
Status :: Forbidden => None ,
22
44
} ;
0 commit comments