//@ edition: 2021 //@ run-pass //@ run-flags: {{sysroot-base}} {{target-linker}} //@ ignore-stage1 (requires matching sysroot built with in-tree compiler) // Regression test for . // // This test ensures that `compile_input` can be called twice in one task // without causing a panic. #![feature(rustc_private)] extern crate rustc_driver; extern crate rustc_interface; extern crate rustc_session; extern crate rustc_span; use std::path::{Path, PathBuf}; use rustc_interface::Linker; use rustc_interface::interface; use rustc_session::config::{Input, Options, OutFileName, OutputType, OutputTypes}; use rustc_span::FileName; fn main() { let src = r#" fn main() {} "#; let args: Vec = std::env::args().collect(); if args.len() < 2 { panic!("expected sysroot (and optional linker)"); } let sysroot = PathBuf::from(&args[1]); let linker = args.get(2).map(PathBuf::from); // compiletest sets the current dir to `output_base_dir` when running. let tmpdir = std::env::current_dir().unwrap().join("tmp"); std::fs::create_dir_all(&tmpdir).unwrap(); compile(src.to_string(), tmpdir.join("out"), sysroot.clone(), linker.as_deref()); compile(src.to_string(), tmpdir.join("out"), sysroot.clone(), linker.as_deref()); } fn compile(code: String, output: PathBuf, sysroot: PathBuf, linker: Option<&Path>) { let mut opts = Options::default(); opts.output_types = OutputTypes::new(&[(OutputType::Exe, None)]); opts.maybe_sysroot = Some(sysroot); if let Some(linker) = linker { opts.cg.linker = Some(linker.to_owned()); } let name = FileName::anon_source_code(&code); let input = Input::Str { name, input: code }; let config = interface::Config { opts, crate_cfg: Default::default(), crate_check_cfg: Default::default(), input, output_file: Some(OutFileName::Real(output)), output_dir: None, ice_file: None, file_loader: None, locale_resources: Vec::new(), lint_caps: Default::default(), psess_created: None, hash_untracked_state: None, register_lints: None, override_queries: None, make_codegen_backend: None, registry: rustc_driver::diagnostics_registry(), using_internal_features: std::sync::Arc::default(), expanded_args: Default::default(), }; interface::run_compiler(config, |compiler| { let linker = compiler.enter(|queries| { queries.global_ctxt()?.enter(|tcx| { tcx.analysis(())?; Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend) }) }); linker.unwrap().link(&compiler.sess, &*compiler.codegen_backend).unwrap(); }); }