@@ -314,7 +314,7 @@ impl Profiles {
314
314
mode : CompileMode ,
315
315
profile_kind : ProfileKind ,
316
316
) -> Profile {
317
- let profile_name = if !self . named_profiles_enabled {
317
+ let ( profile_name, inherits ) = if !self . named_profiles_enabled {
318
318
// With the feature disabled, we degrade `--profile` back to the
319
319
// `--release` and `--debug` predicates, and convert back from
320
320
// ProfileKind::Custom instantiation.
@@ -328,9 +328,9 @@ impl Profiles {
328
328
match mode {
329
329
CompileMode :: Test | CompileMode :: Bench => {
330
330
if release {
331
- "bench"
331
+ ( "bench" , Some ( "release" ) )
332
332
} else {
333
- "test"
333
+ ( "test" , Some ( "dev" ) )
334
334
}
335
335
}
336
336
CompileMode :: Build
@@ -342,25 +342,33 @@ impl Profiles {
342
342
// ancestor's profile. However, `cargo clean -p` can hit this
343
343
// path.
344
344
if release {
345
- "release"
345
+ ( "release" , None )
346
346
} else {
347
- "dev"
347
+ ( "dev" , None )
348
348
}
349
349
}
350
- CompileMode :: Doc { .. } => "doc" ,
350
+ CompileMode :: Doc { .. } => ( "doc" , None ) ,
351
351
}
352
352
} else {
353
- profile_kind. name ( )
353
+ ( profile_kind. name ( ) , None )
354
354
} ;
355
355
let maker = match self . by_name . get ( profile_name) {
356
356
None => panic ! ( "Profile {} undefined" , profile_name) ,
357
357
Some ( r) => r,
358
358
} ;
359
359
let mut profile = maker. get_profile ( Some ( pkg_id) , is_member, unit_for) ;
360
- // `panic` should not be set for tests/benches, or any of their
361
- // dependencies.
362
- if !unit_for. is_panic_abort_ok ( ) || mode. is_any_test ( ) {
363
- profile. panic = PanicStrategy :: Unwind ;
360
+
361
+ // Dealing with `panic=abort` and `panic=unwind` requires some special
362
+ // treatment. Be sure to process all the various options here.
363
+ match unit_for. panic_setting ( ) {
364
+ PanicSetting :: AlwaysUnwind => profile. panic = PanicStrategy :: Unwind ,
365
+ PanicSetting :: ReadProfile => { }
366
+ PanicSetting :: Inherit => {
367
+ if let Some ( inherits) = inherits {
368
+ let maker = self . by_name . get ( inherits) . unwrap ( ) ;
369
+ profile. panic = maker. get_profile ( Some ( pkg_id) , is_member, unit_for) . panic ;
370
+ }
371
+ }
364
372
}
365
373
366
374
// Incremental can be globally overridden.
@@ -880,11 +888,25 @@ pub struct UnitFor {
880
888
/// any of its dependencies. This enables `build-override` profiles for
881
889
/// these targets.
882
890
build : bool ,
883
- /// This is true if it is *allowed* to set the `panic=abort` flag. Currently
884
- /// this is false for test/bench targets and all their dependencies, and
885
- /// "for_host" units such as proc macro and custom build scripts and their
886
- /// dependencies.
887
- panic_abort_ok : bool ,
891
+ /// How Cargo processes the `panic` setting or profiles. This is done to
892
+ /// handle test/benches inheriting from dev/release, as well as forcing
893
+ /// `for_host` units to always unwind.
894
+ panic_setting : PanicSetting ,
895
+ }
896
+
897
+ #[ derive( Copy , Clone , Debug , Eq , PartialEq , Hash , Ord , PartialOrd ) ]
898
+ enum PanicSetting {
899
+ /// Used to force a unit to always be compiled with the `panic=unwind`
900
+ /// strategy, notably for build scripts, proc macros, etc.
901
+ AlwaysUnwind ,
902
+
903
+ /// Indicates that this unit will read its `profile` setting and use
904
+ /// whatever is configured there.
905
+ ReadProfile ,
906
+
907
+ /// This unit will ignore its `panic` setting in its profile and will
908
+ /// instead inherit it from the `dev` or `release` profile, as appropriate.
909
+ Inherit ,
888
910
}
889
911
890
912
impl UnitFor {
@@ -893,42 +915,67 @@ impl UnitFor {
893
915
pub fn new_normal ( ) -> UnitFor {
894
916
UnitFor {
895
917
build : false ,
896
- panic_abort_ok : true ,
918
+ panic_setting : PanicSetting :: ReadProfile ,
897
919
}
898
920
}
899
921
900
922
/// A unit for a custom build script or its dependencies.
901
923
pub fn new_build ( ) -> UnitFor {
902
924
UnitFor {
903
925
build : true ,
904
- panic_abort_ok : false ,
926
+ // Force build scripts to always use `panic=unwind` for now to
927
+ // maximally share dependencies with procedural macros.
928
+ panic_setting : PanicSetting :: AlwaysUnwind ,
905
929
}
906
930
}
907
931
908
932
/// A unit for a proc macro or compiler plugin or their dependencies.
909
933
pub fn new_compiler ( ) -> UnitFor {
910
934
UnitFor {
911
935
build : false ,
912
- panic_abort_ok : false ,
936
+ // Force plugins to use `panic=abort` so panics in the compiler do
937
+ // not abort the process but instead end with a reasonable error
938
+ // message that involves catching the panic in the compiler.
939
+ panic_setting : PanicSetting :: AlwaysUnwind ,
913
940
}
914
941
}
915
942
916
943
/// A unit for a test/bench target or their dependencies.
917
- pub fn new_test ( ) -> UnitFor {
944
+ ///
945
+ /// Note that `config` is taken here for unstable CLI features to detect
946
+ /// whether `panic=abort` is supported for tests. Historical versions of
947
+ /// rustc did not support this, but newer versions do with an unstable
948
+ /// compiler flag.
949
+ pub fn new_test ( config : & Config ) -> UnitFor {
918
950
UnitFor {
919
951
build : false ,
920
- panic_abort_ok : false ,
952
+ // We're testing out an unstable feature (`-Zpanic-abort-tests`)
953
+ // which inherits the panic setting from the dev/release profile
954
+ // (basically avoid recompiles) but historical defaults required
955
+ // that we always unwound.
956
+ panic_setting : if config. cli_unstable ( ) . panic_abort_tests {
957
+ PanicSetting :: Inherit
958
+ } else {
959
+ PanicSetting :: AlwaysUnwind
960
+ } ,
921
961
}
922
962
}
923
963
924
964
/// Creates a variant based on `for_host` setting.
925
965
///
926
- /// When `for_host` is true, this clears `panic_abort_ok` in a sticky fashion so
927
- /// that all its dependencies also have `panic_abort_ok=false`.
966
+ /// When `for_host` is true, this clears `panic_abort_ok` in a sticky
967
+ /// fashion so that all its dependencies also have `panic_abort_ok=false`.
968
+ /// This'll help ensure that once we start compiling for the host platform
969
+ /// (build scripts, plugins, proc macros, etc) we'll share the same build
970
+ /// graph where everything is `panic=unwind`.
928
971
pub fn with_for_host ( self , for_host : bool ) -> UnitFor {
929
972
UnitFor {
930
973
build : self . build || for_host,
931
- panic_abort_ok : self . panic_abort_ok && !for_host,
974
+ panic_setting : if for_host {
975
+ PanicSetting :: AlwaysUnwind
976
+ } else {
977
+ self . panic_setting
978
+ } ,
932
979
}
933
980
}
934
981
@@ -938,28 +985,32 @@ impl UnitFor {
938
985
self . build
939
986
}
940
987
941
- /// Returns `true` if this unit is allowed to set the `panic` compiler flag.
942
- pub fn is_panic_abort_ok ( self ) -> bool {
943
- self . panic_abort_ok
988
+ /// Returns how `panic` settings should be handled for this profile
989
+ fn panic_setting ( self ) -> PanicSetting {
990
+ self . panic_setting
944
991
}
945
992
946
993
/// All possible values, used by `clean`.
947
994
pub fn all_values ( ) -> & ' static [ UnitFor ] {
948
- static ALL : [ UnitFor ; 3 ] = [
995
+ static ALL : & [ UnitFor ] = & [
949
996
UnitFor {
950
997
build : false ,
951
- panic_abort_ok : true ,
998
+ panic_setting : PanicSetting :: ReadProfile ,
952
999
} ,
953
1000
UnitFor {
954
1001
build : true ,
955
- panic_abort_ok : false ,
1002
+ panic_setting : PanicSetting :: AlwaysUnwind ,
1003
+ } ,
1004
+ UnitFor {
1005
+ build : false ,
1006
+ panic_setting : PanicSetting :: AlwaysUnwind ,
956
1007
} ,
957
1008
UnitFor {
958
1009
build : false ,
959
- panic_abort_ok : false ,
1010
+ panic_setting : PanicSetting :: Inherit ,
960
1011
} ,
961
1012
] ;
962
- & ALL
1013
+ ALL
963
1014
}
964
1015
}
965
1016
0 commit comments