@@ -181,7 +181,7 @@ pub enum CargoKaniSubcommand {
181
181
pub struct VerificationArgs {
182
182
/// Temporary option to trigger assess mode for out test suite
183
183
/// where we are able to add options but not subcommands
184
- #[ arg( long, hide = true , requires ( "enable_unstable" ) ) ]
184
+ #[ arg( long, hide = true ) ]
185
185
pub assess : bool ,
186
186
187
187
/// Generate concrete playback unit test.
@@ -195,9 +195,9 @@ pub struct VerificationArgs {
195
195
#[ arg( long, hide_short_help = true ) ]
196
196
pub keep_temps : bool ,
197
197
198
- /// Generate C file equivalent to inputted program.
199
- /// This feature is unstable and it requires `--enable- unstable` to be used
200
- #[ arg( long, hide_short_help = true , requires ( "enable_unstable" ) ) ]
198
+ /// Generate C file equivalent to inputted program for debug purpose .
199
+ /// This feature is unstable, and it requires `-Z unstable-options ` to be used
200
+ #[ arg( long, hide_short_help = true ) ]
201
201
pub gen_c : bool ,
202
202
203
203
/// Directory for all generated artifacts.
@@ -247,11 +247,10 @@ pub struct VerificationArgs {
247
247
#[ arg( long, value_parser = CbmcSolverValueParser :: new( CbmcSolver :: VARIANTS ) ) ]
248
248
pub solver : Option < CbmcSolver > ,
249
249
/// Pass through directly to CBMC; must be the last flag.
250
- /// This feature is unstable and it requires `--enable_unstable ` to be used
250
+ /// This feature is unstable and it requires `-Z unstable-options ` to be used
251
251
#[ arg(
252
252
long,
253
253
allow_hyphen_values = true ,
254
- requires( "enable_unstable" ) ,
255
254
num_args( 0 ..)
256
255
) ]
257
256
// consumes everything
@@ -261,19 +260,19 @@ pub struct VerificationArgs {
261
260
/// Omit the flag entirely to run sequentially (i.e. one thread).
262
261
/// Pass -j to run with the thread pool's default number of threads.
263
262
/// Pass -j <N> to specify N threads.
264
- #[ arg( short, long, hide_short_help = true , requires ( "enable_unstable" ) ) ]
263
+ #[ arg( short, long, hide_short_help = true ) ]
265
264
pub jobs : Option < Option < usize > > ,
266
265
267
266
/// Enable extra pointer checks such as invalid pointers in relation operations and pointer
268
267
/// arithmetic overflow.
269
268
/// This feature is unstable and it may yield false counter examples. It requires
270
- /// `--enable- unstable` to be used
271
- #[ arg( long, hide_short_help = true , requires ( "enable_unstable" ) ) ]
269
+ /// `-Z unstable-options ` to be used
270
+ #[ arg( long, hide_short_help = true ) ]
272
271
pub extra_pointer_checks : bool ,
273
272
274
273
/// Restrict the targets of virtual table function pointer calls.
275
- /// This feature is unstable and it requires `--enable-unstable ` to be used
276
- #[ arg( long, hide_short_help = true , requires ( "enable_unstable" ) ) ]
274
+ /// This feature is unstable and it requires `-Z restrict-vtable ` to be used
275
+ #[ arg( long, hide_short_help = true , conflicts_with = "no_restrict_vtable" ) ]
277
276
pub restrict_vtable : bool ,
278
277
/// Disable restricting the targets of virtual table function pointer calls
279
278
#[ arg( long, hide_short_help = true ) ]
@@ -284,26 +283,25 @@ pub struct VerificationArgs {
284
283
285
284
/// Do not error out for crates containing `global_asm!`.
286
285
/// This option may impact the soundness of the analysis and may cause false proofs and/or counterexamples
287
- #[ arg( long, hide_short_help = true , requires ( "enable_unstable" ) ) ]
286
+ #[ arg( long, hide_short_help = true ) ]
288
287
pub ignore_global_asm : bool ,
289
288
290
289
/// Write the GotoC symbol table to a file in JSON format instead of goto binary format.
291
290
#[ arg( long, hide_short_help = true ) ]
292
291
pub write_json_symtab : bool ,
293
292
294
293
/// Execute CBMC's sanity checks to ensure the goto-program we generate is correct.
295
- #[ arg( long, hide_short_help = true , requires ( "enable_unstable" ) ) ]
294
+ #[ arg( long, hide_short_help = true ) ]
296
295
pub run_sanity_checks : bool ,
297
296
298
297
/// Disable CBMC's slice formula which prevents values from being assigned to redundant variables in traces.
299
- #[ arg( long, hide_short_help = true , requires ( "enable_unstable" ) ) ]
298
+ #[ arg( long, hide_short_help = true ) ]
300
299
pub no_slice_formula : bool ,
301
300
302
301
/// Synthesize loop contracts for all loops.
303
302
#[ arg(
304
303
long,
305
304
hide_short_help = true ,
306
- requires( "enable_unstable" ) ,
307
305
conflicts_with( "unwind" ) ,
308
306
conflicts_with( "default_unwind" )
309
307
) ]
@@ -351,6 +349,8 @@ pub struct VerificationArgs {
351
349
impl VerificationArgs {
352
350
pub fn restrict_vtable ( & self ) -> bool {
353
351
self . restrict_vtable
352
+ || ( self . common_args . unstable_features . contains ( UnstableFeature :: RestrictVtable )
353
+ && !self . no_restrict_vtable )
354
354
// if we flip the default, this will become: !self.no_restrict_vtable
355
355
}
356
356
@@ -538,16 +538,14 @@ impl ValidateArgs for CargoKaniArgs {
538
538
fn validate ( & self ) -> Result < ( ) , Error > {
539
539
self . verify_opts . validate ( ) ?;
540
540
self . command . validate ( ) ?;
541
- // --assess requires --enable-unstable, but the subcommand needs manual checking
542
- if ( matches ! ( self . command, Some ( CargoKaniSubcommand :: Assess ( _) ) ) || self . verify_opts . assess )
543
- && !self . verify_opts . common_args . enable_unstable
544
- {
545
- return Err ( Error :: raw (
546
- ErrorKind :: MissingRequiredArgument ,
547
- "Assess is unstable and requires 'cargo kani --enable-unstable assess'" ,
548
- ) ) ;
549
- }
550
- Ok ( ( ) )
541
+
542
+ // --assess requires -Z unstable-options, but the subcommand needs manual checking
543
+ self . verify_opts . common_args . check_unstable (
544
+ ( matches ! ( self . command, Some ( CargoKaniSubcommand :: Assess ( _) ) )
545
+ || self . verify_opts . assess ) ,
546
+ "assess" ,
547
+ UnstableFeature :: UnstableOptions ,
548
+ )
551
549
}
552
550
}
553
551
@@ -630,20 +628,78 @@ impl ValidateArgs for VerificationArgs {
630
628
}
631
629
}
632
630
633
- if self . concrete_playback . is_some ( )
634
- && !self . common_args . unstable_features . contains ( UnstableFeature :: ConcretePlayback )
635
- {
636
- if self . common_args . enable_unstable {
637
- print_deprecated ( & self . common_args , "--enable-unstable" , "-Z concrete-playback" ) ;
638
- } else {
639
- return Err ( Error :: raw (
640
- ErrorKind :: MissingRequiredArgument ,
641
- "The `--concrete-playback` argument is unstable and requires `-Z \
642
- concrete-playback` to be used.",
643
- ) ) ;
644
- }
631
+ self . common_args . check_unstable (
632
+ self . concrete_playback . is_some ( ) ,
633
+ "--concrete-playback" ,
634
+ UnstableFeature :: ConcretePlayback ,
635
+ ) ?;
636
+
637
+ self . common_args . check_unstable (
638
+ !self . c_lib . is_empty ( ) ,
639
+ "--c-lib" ,
640
+ UnstableFeature :: CFfi ,
641
+ ) ?;
642
+
643
+ self . common_args . check_unstable ( self . gen_c , "--gen-c" , UnstableFeature :: UnstableOptions ) ?;
644
+
645
+ self . common_args . check_unstable (
646
+ !self . cbmc_args . is_empty ( ) ,
647
+ "--cbmc-args" ,
648
+ UnstableFeature :: UnstableOptions ,
649
+ ) ?;
650
+
651
+ self . common_args . check_unstable (
652
+ self . jobs . is_some ( ) ,
653
+ "--jobs" ,
654
+ UnstableFeature :: UnstableOptions ,
655
+ ) ?;
656
+
657
+ self . common_args . check_unstable (
658
+ self . extra_pointer_checks ,
659
+ "--extra-pointer-checks" ,
660
+ UnstableFeature :: UnstableOptions ,
661
+ ) ?;
662
+
663
+ self . common_args . check_unstable (
664
+ self . ignore_global_asm ,
665
+ "--ignore-global-asm" ,
666
+ UnstableFeature :: UnstableOptions ,
667
+ ) ?;
668
+
669
+ self . common_args . check_unstable (
670
+ self . run_sanity_checks ,
671
+ "--run-sanity-checks" ,
672
+ UnstableFeature :: UnstableOptions ,
673
+ ) ?;
674
+
675
+ self . common_args . check_unstable (
676
+ self . no_slice_formula ,
677
+ "--no-slice-formula" ,
678
+ UnstableFeature :: UnstableOptions ,
679
+ ) ?;
680
+
681
+ self . common_args . check_unstable (
682
+ self . synthesize_loop_contracts ,
683
+ "--synthesize-loop-contracts" ,
684
+ UnstableFeature :: UnstableOptions ,
685
+ ) ?;
686
+
687
+ if self . restrict_vtable {
688
+ // Deprecated `--restrict-vtable` in favor our `-Z restrict-vtable`.
689
+ print_deprecated ( & self . common_args , "--restrict-vtable" , "-Z restrict-vtable" ) ;
690
+ self . common_args . check_unstable (
691
+ true ,
692
+ "--restrict-vtable" ,
693
+ UnstableFeature :: RestrictVtable ,
694
+ ) ?;
645
695
}
646
696
697
+ self . common_args . check_unstable (
698
+ self . no_restrict_vtable ,
699
+ "--no-restrict-vtable" ,
700
+ UnstableFeature :: RestrictVtable ,
701
+ ) ?;
702
+
647
703
if !self . c_lib . is_empty ( )
648
704
&& !self . common_args . unstable_features . contains ( UnstableFeature :: CFfi )
649
705
{
@@ -787,7 +843,7 @@ mod tests {
787
843
let a = StandaloneArgs :: try_parse_from ( vec ! [
788
844
"kani" ,
789
845
"file.rs" ,
790
- "--enable-unstable " ,
846
+ "-Zunstable-options " ,
791
847
"--cbmc-args" ,
792
848
"--multiple" ,
793
849
"args" ,
@@ -798,7 +854,7 @@ mod tests {
798
854
let _b = StandaloneArgs :: try_parse_from ( vec ! [
799
855
"kani" ,
800
856
"file.rs" ,
801
- "--enable-unstable " ,
857
+ "-Zunstable-options " ,
802
858
"--cbmc-args" ,
803
859
] )
804
860
. unwrap ( ) ;
@@ -840,21 +896,21 @@ mod tests {
840
896
assert ! ( b. is_ok( ) ) ;
841
897
}
842
898
843
- fn check ( args : & str , require_unstable : bool , pred : fn ( StandaloneArgs ) -> bool ) {
899
+ fn check ( args : & str , feature : Option < UnstableFeature > , pred : fn ( StandaloneArgs ) -> bool ) {
844
900
let mut res = parse_unstable_disabled ( & args) ;
845
- if require_unstable {
846
- // Should fail without --enable- unstable.
901
+ if let Some ( unstable ) = feature {
902
+ // Should fail without -Z unstable-options .
847
903
assert_eq ! ( res. unwrap_err( ) . kind( ) , ErrorKind :: MissingRequiredArgument ) ;
848
- // Should succeed with --enable- unstable.
849
- res = parse_unstable_enabled ( & args) ;
904
+ // Should succeed with -Z unstable-options .
905
+ res = parse_unstable_enabled ( & args, unstable ) ;
850
906
}
851
907
assert ! ( res. is_ok( ) ) ;
852
908
assert ! ( pred( res. unwrap( ) ) ) ;
853
909
}
854
910
855
911
macro_rules! check_unstable_flag {
856
912
( $args: expr, $name: ident) => {
857
- check( $args, true , |p| p. verify_opts. $name)
913
+ check( $args, Some ( UnstableFeature :: UnstableOptions ) , |p| p. verify_opts. $name)
858
914
} ;
859
915
}
860
916
@@ -891,22 +947,35 @@ mod tests {
891
947
892
948
fn parse_unstable_disabled ( args : & str ) -> Result < StandaloneArgs , Error > {
893
949
let args = format ! ( "kani file.rs {args}" ) ;
894
- StandaloneArgs :: try_parse_from ( args. split ( ' ' ) )
950
+ let parse_res = StandaloneArgs :: try_parse_from ( args. split ( ' ' ) ) ?;
951
+ parse_res. verify_opts . validate ( ) ?;
952
+ Ok ( parse_res)
895
953
}
896
954
897
- fn parse_unstable_enabled ( args : & str ) -> Result < StandaloneArgs , Error > {
898
- let args = format ! ( "kani --enable-unstable file.rs {args}" ) ;
899
- StandaloneArgs :: try_parse_from ( args. split ( ' ' ) )
955
+ fn parse_unstable_enabled (
956
+ args : & str ,
957
+ unstable : UnstableFeature ,
958
+ ) -> Result < StandaloneArgs , Error > {
959
+ let args = format ! ( "kani -Z {} file.rs {args}" , unstable) ;
960
+ let parse_res = StandaloneArgs :: try_parse_from ( args. split ( ' ' ) ) ?;
961
+ parse_res. verify_opts . validate ( ) ?;
962
+ Ok ( parse_res)
900
963
}
901
964
902
965
#[ test]
903
966
fn check_restrict_vtable_unstable ( ) {
904
- check_unstable_flag ! ( "--restrict-vtable" , restrict_vtable) ;
967
+ let restrict_vtable = |args : StandaloneArgs | args. verify_opts . restrict_vtable ( ) ;
968
+ check ( "--restrict-vtable" , Some ( UnstableFeature :: RestrictVtable ) , restrict_vtable) ;
905
969
}
906
970
907
971
#[ test]
908
972
fn check_restrict_cbmc_args ( ) {
909
- check_opt ! ( "--cbmc-args --json-ui" , true , cbmc_args, vec![ "--json-ui" ] ) ;
973
+ check_opt ! (
974
+ "--cbmc-args --json-ui" ,
975
+ Some ( UnstableFeature :: UnstableOptions ) ,
976
+ cbmc_args,
977
+ vec![ "--json-ui" ]
978
+ ) ;
910
979
}
911
980
912
981
#[ test]
@@ -938,11 +1007,11 @@ mod tests {
938
1007
#[ test]
939
1008
fn check_concrete_playback_conflicts ( ) {
940
1009
expect_validation_error (
941
- "kani --concrete-playback=print --quiet --enable-unstable test.rs" ,
1010
+ "kani --concrete-playback=print --quiet -Z concrete-playback test.rs" ,
942
1011
ErrorKind :: ArgumentConflict ,
943
1012
) ;
944
1013
expect_validation_error (
945
- "kani --concrete-playback=inplace --output-format=old --enable-unstable test.rs" ,
1014
+ "kani --concrete-playback=inplace --output-format=old -Z concrete-playback test.rs" ,
946
1015
ErrorKind :: ArgumentConflict ,
947
1016
) ;
948
1017
}
@@ -1010,7 +1079,7 @@ mod tests {
1010
1079
1011
1080
#[ test]
1012
1081
fn check_cbmc_args_lean_backend ( ) {
1013
- let args = "kani input.rs -Z lean --enable- unstable --cbmc-args --object-bits 10"
1082
+ let args = "kani input.rs -Z lean -Z unstable-options --cbmc-args --object-bits 10"
1014
1083
. split_whitespace ( ) ;
1015
1084
let err = StandaloneArgs :: try_parse_from ( args) . unwrap ( ) . validate ( ) . unwrap_err ( ) ;
1016
1085
assert_eq ! ( err. kind( ) , ErrorKind :: ArgumentConflict ) ;
0 commit comments