@@ -4,6 +4,7 @@ use crate::core::compiler::context::Metadata;
44use crate :: core:: compiler:: job_queue:: JobState ;
55use crate :: core:: { profiles:: ProfileRoot , PackageId } ;
66use crate :: util:: errors:: { CargoResult , CargoResultExt } ;
7+ use crate :: util:: interning:: InternedString ;
78use crate :: util:: machine_message:: { self , Message } ;
89use crate :: util:: { self , internal, paths, profile} ;
910use cargo_platform:: Cfg ;
@@ -267,7 +268,8 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
267268 }
268269 } )
269270 . collect :: < Vec < _ > > ( ) ;
270- let pkg_name = unit. pkg . to_string ( ) ;
271+ let pkg_name = unit. pkg . name ( ) ;
272+ let pkg_descr = unit. pkg . to_string ( ) ;
271273 let build_script_outputs = Arc :: clone ( & cx. build_script_outputs ) ;
272274 let id = unit. pkg . package_id ( ) ;
273275 let output_file = script_run_dir. join ( "output" ) ;
@@ -276,7 +278,8 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
276278 let host_target_root = cx. files ( ) . host_dest ( ) . to_path_buf ( ) ;
277279 let all = (
278280 id,
279- pkg_name. clone ( ) ,
281+ pkg_name,
282+ pkg_descr. clone ( ) ,
280283 Arc :: clone ( & build_script_outputs) ,
281284 output_file. clone ( ) ,
282285 script_out_dir. clone ( ) ,
@@ -291,6 +294,7 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
291294 paths:: create_dir_all ( & script_out_dir) ?;
292295
293296 let extra_link_arg = cx. bcx . config . cli_unstable ( ) . extra_link_arg ;
297+ let nightly_features_allowed = cx. bcx . config . nightly_features_allowed ;
294298
295299 // Prepare the unit of "dirty work" which will actually run the custom build
296300 // command.
@@ -365,7 +369,7 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
365369 } ,
366370 true ,
367371 )
368- . chain_err ( || format ! ( "failed to run custom build command for `{}`" , pkg_name ) ) ;
372+ . chain_err ( || format ! ( "failed to run custom build command for `{}`" , pkg_descr ) ) ;
369373
370374 if let Err ( error) = output {
371375 insert_warnings_in_build_outputs (
@@ -394,10 +398,12 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
394398 paths:: write ( & root_output_file, util:: path2bytes ( & script_out_dir) ?) ?;
395399 let parsed_output = BuildOutput :: parse (
396400 & output. stdout ,
397- & pkg_name,
401+ pkg_name,
402+ & pkg_descr,
398403 & script_out_dir,
399404 & script_out_dir,
400405 extra_link_arg,
406+ nightly_features_allowed,
401407 ) ?;
402408
403409 if json_messages {
@@ -414,15 +420,17 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
414420 // itself to run when we actually end up just discarding what we calculated
415421 // above.
416422 let fresh = Work :: new ( move |state| {
417- let ( id, pkg_name, build_script_outputs, output_file, script_out_dir) = all;
423+ let ( id, pkg_name, pkg_descr , build_script_outputs, output_file, script_out_dir) = all;
418424 let output = match prev_output {
419425 Some ( output) => output,
420426 None => BuildOutput :: parse_file (
421427 & output_file,
422- & pkg_name,
428+ pkg_name,
429+ & pkg_descr,
423430 & prev_script_out_dir,
424431 & script_out_dir,
425432 extra_link_arg,
433+ nightly_features_allowed,
426434 ) ?,
427435 } ;
428436
@@ -469,29 +477,35 @@ fn insert_warnings_in_build_outputs(
469477impl BuildOutput {
470478 pub fn parse_file (
471479 path : & Path ,
472- pkg_name : & str ,
480+ pkg_name : InternedString ,
481+ pkg_descr : & str ,
473482 script_out_dir_when_generated : & Path ,
474483 script_out_dir : & Path ,
475484 extra_link_arg : bool ,
485+ nightly_features_allowed : bool ,
476486 ) -> CargoResult < BuildOutput > {
477487 let contents = paths:: read_bytes ( path) ?;
478488 BuildOutput :: parse (
479489 & contents,
480490 pkg_name,
491+ pkg_descr,
481492 script_out_dir_when_generated,
482493 script_out_dir,
483494 extra_link_arg,
495+ nightly_features_allowed,
484496 )
485497 }
486498
487499 // Parses the output of a script.
488500 // The `pkg_name` is used for error messages.
489501 pub fn parse (
490502 input : & [ u8 ] ,
491- pkg_name : & str ,
503+ pkg_name : InternedString ,
504+ pkg_descr : & str ,
492505 script_out_dir_when_generated : & Path ,
493506 script_out_dir : & Path ,
494507 extra_link_arg : bool ,
508+ nightly_features_allowed : bool ,
495509 ) -> CargoResult < BuildOutput > {
496510 let mut library_paths = Vec :: new ( ) ;
497511 let mut library_links = Vec :: new ( ) ;
@@ -502,7 +516,7 @@ impl BuildOutput {
502516 let mut rerun_if_changed = Vec :: new ( ) ;
503517 let mut rerun_if_env_changed = Vec :: new ( ) ;
504518 let mut warnings = Vec :: new ( ) ;
505- let whence = format ! ( "build script of `{}`" , pkg_name ) ;
519+ let whence = format ! ( "build script of `{}`" , pkg_descr ) ;
506520
507521 for line in input. split ( |b| * b == b'\n' ) {
508522 let line = match str:: from_utf8 ( line) {
@@ -562,7 +576,37 @@ impl BuildOutput {
562576 }
563577 }
564578 "rustc-cfg" => cfgs. push ( value. to_string ( ) ) ,
565- "rustc-env" => env. push ( BuildOutput :: parse_rustc_env ( & value, & whence) ?) ,
579+ "rustc-env" => {
580+ let ( key, val) = BuildOutput :: parse_rustc_env ( & value, & whence) ?;
581+ // Build scripts aren't allowed to set RUSTC_BOOTSTRAP.
582+ // See https://github.com/rust-lang/cargo/issues/7088.
583+ if key == "RUSTC_BOOTSTRAP" {
584+ // If RUSTC_BOOTSTRAP is already set, the user of Cargo knows about
585+ // bootstrap and still wants to override the channel. Give them a way to do
586+ // so, but still emit a warning that the current crate shouldn't be trying
587+ // to set RUSTC_BOOTSTRAP.
588+ // If this is a nightly build, setting RUSTC_BOOTSTRAP wouldn't affect the
589+ // behavior, so still only give a warning.
590+ if nightly_features_allowed {
591+ warnings. push ( format ! ( "Cannot set `RUSTC_BOOTSTRAP={}` from {}.\n \
592+ note: Crates cannot set `RUSTC_BOOTSTRAP` themselves, as doing so would subvert the stability guarantees of Rust for your project.",
593+ val, whence
594+ ) ) ;
595+ } else {
596+ // Setting RUSTC_BOOTSTRAP would change the behavior of the crate.
597+ // Abort with an error.
598+ anyhow:: bail!( "Cannot set `RUSTC_BOOTSTRAP={}` from {}.\n \
599+ note: Crates cannot set `RUSTC_BOOTSTRAP` themselves, as doing so would subvert the stability guarantees of Rust for your project.\n \
600+ help: If you're sure you want to do this in your project, set the environment variable `RUSTC_BOOTSTRAP={}` before running cargo instead.",
601+ val,
602+ whence,
603+ pkg_name,
604+ ) ;
605+ }
606+ } else {
607+ env. push ( ( key, val) ) ;
608+ }
609+ }
566610 "warning" => warnings. push ( value. to_string ( ) ) ,
567611 "rerun-if-changed" => rerun_if_changed. push ( PathBuf :: from ( value) ) ,
568612 "rerun-if-env-changed" => rerun_if_env_changed. push ( value. to_string ( ) ) ,
@@ -813,10 +857,12 @@ fn prev_build_output(cx: &mut Context<'_, '_>, unit: &Unit) -> (Option<BuildOutp
813857 (
814858 BuildOutput :: parse_file (
815859 & output_file,
860+ unit. pkg . name ( ) ,
816861 & unit. pkg . to_string ( ) ,
817862 & prev_script_out_dir,
818863 & script_out_dir,
819864 extra_link_arg,
865+ cx. bcx . config . nightly_features_allowed ,
820866 )
821867 . ok ( ) ,
822868 prev_script_out_dir,
0 commit comments