@@ -16,9 +16,9 @@ use rustc_session::lint::BuiltinLintDiag;
16
16
use rustc_session:: lint:: builtin:: UNEXPECTED_CFGS ;
17
17
use rustc_session:: parse:: feature_err;
18
18
use rustc_session:: { RustcVersion , Session } ;
19
+ use rustc_span:: Span ;
19
20
use rustc_span:: hygiene:: Transparency ;
20
21
use rustc_span:: symbol:: { Symbol , kw, sym} ;
21
- use rustc_span:: { DUMMY_SP , Span } ;
22
22
23
23
use crate :: fluent_generated;
24
24
use crate :: session_diagnostics:: { self , IncorrectReprFormatGenericCause } ;
@@ -92,13 +92,15 @@ impl Stability {
92
92
#[ derive( HashStable_Generic ) ]
93
93
pub struct ConstStability {
94
94
pub level : StabilityLevel ,
95
- /// This can be `None` for functions that are not even const-unstable, but
96
- /// are tracked here for the purpose of `safe_to_expose_on_stable`.
95
+ /// Says whether this function has an explicit `rustc_const_(un)stable` attribute.
96
+ /// If `false`, the const stability information was inferred from the regular
97
+ /// stability information.
98
+ pub has_const_stable_attr : bool ,
99
+ /// This can be `None` for functions that are not const-callable from outside code under any
100
+ /// feature gate, but are tracked here for the purpose of `safe_to_expose_on_stable`.
97
101
pub feature : Option < Symbol > ,
98
- /// A function that is marked as "safe to expose on stable" must not use any unstable const
99
- /// language features or intrinsics, and all the functions it calls must also be safe to expose
100
- /// on stable. If `level` is `Stable`, this must be `true`.
101
- pub safe_to_expose_on_stable : bool ,
102
+ /// This is true iff the `const_stable_indirect` attribute is present.
103
+ pub const_stable_indirect : bool ,
102
104
/// whether the function has a `#[rustc_promotable]` attribute
103
105
pub promotable : bool ,
104
106
}
@@ -274,14 +276,10 @@ pub fn find_stability(
274
276
275
277
/// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable`
276
278
/// attributes in `attrs`. Returns `None` if no stability attributes are found.
277
- ///
278
- /// `inherited_feature_gate` says which feature gate this function should be under if it doesn't
279
- /// declare a gate itself, but has `#[rustc_const_stable_indirect]`.
280
279
pub fn find_const_stability (
281
280
sess : & Session ,
282
281
attrs : & [ Attribute ] ,
283
282
item_sp : Span ,
284
- inherited_feature_gate : Option < Symbol > ,
285
283
) -> Option < ( ConstStability , Span ) > {
286
284
let mut const_stab: Option < ( ConstStability , Span ) > = None ;
287
285
let mut promotable = false ;
@@ -302,8 +300,9 @@ pub fn find_const_stability(
302
300
const_stab = Some ( (
303
301
ConstStability {
304
302
level,
303
+ has_const_stable_attr : true ,
305
304
feature : Some ( feature) ,
306
- safe_to_expose_on_stable : false ,
305
+ const_stable_indirect : false ,
307
306
promotable : false ,
308
307
} ,
309
308
attr. span ,
@@ -320,8 +319,9 @@ pub fn find_const_stability(
320
319
const_stab = Some ( (
321
320
ConstStability {
322
321
level,
322
+ has_const_stable_attr : true ,
323
323
feature : Some ( feature) ,
324
- safe_to_expose_on_stable : true ,
324
+ const_stable_indirect : false ,
325
325
promotable : false ,
326
326
} ,
327
327
attr. span ,
@@ -347,36 +347,69 @@ pub fn find_const_stability(
347
347
match & mut const_stab {
348
348
Some ( ( stab, _) ) => {
349
349
if stab. is_const_unstable ( ) {
350
- stab. safe_to_expose_on_stable = true ;
350
+ stab. const_stable_indirect = true ;
351
351
} else {
352
352
_ = sess. dcx ( ) . emit_err ( session_diagnostics:: RustcConstStableIndirectPairing {
353
353
span : item_sp,
354
354
} )
355
355
}
356
356
}
357
357
_ => {
358
- // `#[rustc_const_stable_indirect]` implicitly makes the function unstably const,
359
- // inheriting the feature gate from `#[unstable]` if it xists, or without any
360
- // feature gate otherwise.
361
- let c = ConstStability {
362
- feature : inherited_feature_gate,
363
- safe_to_expose_on_stable : true ,
364
- promotable : false ,
365
- level : StabilityLevel :: Unstable {
366
- reason : UnstableReason :: Default ,
367
- issue : None ,
368
- is_soft : false ,
369
- implied_by : None ,
370
- } ,
371
- } ;
372
- const_stab = Some ( ( c, DUMMY_SP ) ) ;
358
+ // We ignore the `#[rustc_const_stable_indirect]` here, it should be picked up by
359
+ // the `default_const_unstable` logic.
373
360
}
374
361
}
375
362
}
376
363
377
364
const_stab
378
365
}
379
366
367
+ /// Called for `fn` that don't have a const stability.
368
+ ///
369
+ /// `effective_reg_stability` must be the effecive regular stability, i.e. after applying all the
370
+ /// rules about "inherited" stability.
371
+ pub fn default_const_stability (
372
+ _sess : & Session ,
373
+ is_const_fn : bool ,
374
+ attrs : & [ Attribute ] ,
375
+ effective_reg_stability : Option < & Stability > ,
376
+ ) -> Option < ConstStability > {
377
+ let const_stable_indirect =
378
+ attrs. iter ( ) . any ( |a| a. name_or_empty ( ) == sym:: rustc_const_stable_indirect) ;
379
+ // Intrinsics are *not* `const fn` here, and yet we want to add a default const stability
380
+ // for them if they are marked `const_stable_indirect`.
381
+ if ( is_const_fn || const_stable_indirect)
382
+ && let Some ( reg_stability) = effective_reg_stability
383
+ && reg_stability. level . is_unstable ( )
384
+ {
385
+ // This has a feature gate, reuse that for const stability.
386
+ // We only want to do this if it is an unstable feature gate.
387
+ Some ( ConstStability {
388
+ feature : Some ( reg_stability. feature ) ,
389
+ has_const_stable_attr : false ,
390
+ const_stable_indirect,
391
+ promotable : false ,
392
+ level : reg_stability. level ,
393
+ } )
394
+ } else if const_stable_indirect {
395
+ // Make it const-unstable without a feature gate, to record the `const_stable_indirect`.
396
+ Some ( ConstStability {
397
+ feature : None ,
398
+ has_const_stable_attr : false ,
399
+ const_stable_indirect,
400
+ promotable : false ,
401
+ level : StabilityLevel :: Unstable {
402
+ reason : UnstableReason :: Default ,
403
+ issue : None ,
404
+ is_soft : false ,
405
+ implied_by : None ,
406
+ } ,
407
+ } )
408
+ } else {
409
+ None
410
+ }
411
+ }
412
+
380
413
/// Collects stability info from `rustc_default_body_unstable` attributes in `attrs`.
381
414
/// Returns `None` if no stability attributes are found.
382
415
pub fn find_body_stability (
0 commit comments