@@ -314,7 +314,7 @@ impl Profiles {
314314 mode : CompileMode ,
315315 profile_kind : ProfileKind ,
316316 ) -> Profile {
317- let profile_name = if !self . named_profiles_enabled {
317+ let ( profile_name, inherits ) = if !self . named_profiles_enabled {
318318 // With the feature disabled, we degrade `--profile` back to the
319319 // `--release` and `--debug` predicates, and convert back from
320320 // ProfileKind::Custom instantiation.
@@ -328,9 +328,9 @@ impl Profiles {
328328 match mode {
329329 CompileMode :: Test | CompileMode :: Bench => {
330330 if release {
331- "bench"
331+ ( "bench" , Some ( "release" ) )
332332 } else {
333- "test"
333+ ( "test" , Some ( "dev" ) )
334334 }
335335 }
336336 CompileMode :: Build
@@ -342,25 +342,33 @@ impl Profiles {
342342 // ancestor's profile. However, `cargo clean -p` can hit this
343343 // path.
344344 if release {
345- "release"
345+ ( "release" , None )
346346 } else {
347- "dev"
347+ ( "dev" , None )
348348 }
349349 }
350- CompileMode :: Doc { .. } => "doc" ,
350+ CompileMode :: Doc { .. } => ( "doc" , None ) ,
351351 }
352352 } else {
353- profile_kind. name ( )
353+ ( profile_kind. name ( ) , None )
354354 } ;
355355 let maker = match self . by_name . get ( profile_name) {
356356 None => panic ! ( "Profile {} undefined" , profile_name) ,
357357 Some ( r) => r,
358358 } ;
359359 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+ }
364372 }
365373
366374 // Incremental can be globally overridden.
@@ -880,11 +888,25 @@ pub struct UnitFor {
880888 /// any of its dependencies. This enables `build-override` profiles for
881889 /// these targets.
882890 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 ,
888910}
889911
890912impl UnitFor {
@@ -893,42 +915,67 @@ impl UnitFor {
893915 pub fn new_normal ( ) -> UnitFor {
894916 UnitFor {
895917 build : false ,
896- panic_abort_ok : true ,
918+ panic_setting : PanicSetting :: ReadProfile ,
897919 }
898920 }
899921
900922 /// A unit for a custom build script or its dependencies.
901923 pub fn new_build ( ) -> UnitFor {
902924 UnitFor {
903925 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 ,
905929 }
906930 }
907931
908932 /// A unit for a proc macro or compiler plugin or their dependencies.
909933 pub fn new_compiler ( ) -> UnitFor {
910934 UnitFor {
911935 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 ,
913940 }
914941 }
915942
916943 /// 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 {
918950 UnitFor {
919951 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+ } ,
921961 }
922962 }
923963
924964 /// Creates a variant based on `for_host` setting.
925965 ///
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`.
928971 pub fn with_for_host ( self , for_host : bool ) -> UnitFor {
929972 UnitFor {
930973 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+ } ,
932979 }
933980 }
934981
@@ -938,28 +985,32 @@ impl UnitFor {
938985 self . build
939986 }
940987
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
944991 }
945992
946993 /// All possible values, used by `clean`.
947994 pub fn all_values ( ) -> & ' static [ UnitFor ] {
948- static ALL : [ UnitFor ; 3 ] = [
995+ static ALL : & [ UnitFor ] = & [
949996 UnitFor {
950997 build : false ,
951- panic_abort_ok : true ,
998+ panic_setting : PanicSetting :: ReadProfile ,
952999 } ,
9531000 UnitFor {
9541001 build : true ,
955- panic_abort_ok : false ,
1002+ panic_setting : PanicSetting :: AlwaysUnwind ,
1003+ } ,
1004+ UnitFor {
1005+ build : false ,
1006+ panic_setting : PanicSetting :: AlwaysUnwind ,
9561007 } ,
9571008 UnitFor {
9581009 build : false ,
959- panic_abort_ok : false ,
1010+ panic_setting : PanicSetting :: Inherit ,
9601011 } ,
9611012 ] ;
962- & ALL
1013+ ALL
9631014 }
9641015}
9651016
0 commit comments