From e688f5e3d1ce7430b466730cd5859493899b1f25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 10 Jul 2024 18:44:51 +0200 Subject: [PATCH] [WIP] build_output_filenames: Use already-'resolved' crate name in favor of manually 'resolving' it --- compiler/rustc_attr/src/builtin.rs | 4 --- compiler/rustc_driver_impl/src/lib.rs | 11 +++++--- compiler/rustc_interface/src/passes.rs | 27 ++++++++++++------- compiler/rustc_interface/src/util.rs | 37 +++++++++++++++----------- compiler/rustc_session/src/config.rs | 14 +++++----- 5 files changed, 55 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 34c24a26f7b13..3f99616494519 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -503,10 +503,6 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil } } -pub fn find_crate_name(attrs: &[Attribute]) -> Option { - attr::first_attr_value_str_by_name(attrs, sym::crate_name) -} - #[derive(Clone, Debug)] pub struct Condition { pub name: Symbol, diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 4885de083c5c3..98baf95084c9d 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -759,8 +759,12 @@ fn print_crate_info( // no crate attributes, print out an error and exit return Compilation::Continue; }; - let t_outputs = rustc_interface::util::build_output_filenames(attrs, sess); - let crate_name = passes::get_crate_name(sess, attrs); + let (crate_name, crate_name_origin) = passes::get_crate_name(sess, attrs); + let t_outputs = rustc_interface::util::build_output_filenames( + sess, + crate_name, + crate_name_origin, + ); let crate_types = collect_crate_types(sess, attrs); for &style in &crate_types { let fname = rustc_session::output::filename_for_input( @@ -774,7 +778,8 @@ fn print_crate_info( // no crate attributes, print out an error and exit return Compilation::Continue; }; - println_info!("{}", passes::get_crate_name(sess, attrs)); + let (crate_name, _) = passes::get_crate_name(sess, attrs); + println_info!("{crate_name}"); } Cfg => { let mut cfgs = sess diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index c62e4056c237a..c5bd606bcc05f 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -660,7 +660,7 @@ pub(crate) fn create_global_ctxt<'tcx>( let pre_configured_attrs = rustc_expand::config::pre_configure_attrs(sess, &krate.attrs); - let crate_name = get_crate_name(sess, &pre_configured_attrs); + let (crate_name, crate_name_origin) = get_crate_name(sess, &pre_configured_attrs); let crate_types = collect_crate_types(sess, &pre_configured_attrs); let stable_crate_id = StableCrateId::new( crate_name, @@ -668,7 +668,8 @@ pub(crate) fn create_global_ctxt<'tcx>( sess.opts.cg.metadata.clone(), sess.cfg_version, ); - let outputs = util::build_output_filenames(&pre_configured_attrs, sess); + let outputs = util::build_output_filenames(sess, crate_name, crate_name_origin); + let dep_graph = setup_dep_graph(sess, crate_name)?; let cstore = @@ -1044,7 +1045,7 @@ pub(crate) fn start_codegen<'tcx>( } /// Compute and validate the crate name. -pub fn get_crate_name(sess: &Session, krate_attrs: &[ast::Attribute]) -> Symbol { +pub fn get_crate_name(sess: &Session, krate_attrs: &[ast::Attribute]) -> (Symbol, CrateNameOrigin) { // We unconditionally validate all `#![crate_name]`s even if a crate name was // set on the command line via `--crate-name` which we prioritize over the // crate attributes. We perform the validation here instead of later to ensure @@ -1053,9 +1054,9 @@ pub fn get_crate_name(sess: &Session, krate_attrs: &[ast::Attribute]) -> Symbol let attr_crate_name = validate_and_find_value_str_builtin_attr(sym::crate_name, sess, krate_attrs); - let validate = |name, span| { + let validate = |name, span, origin| { rustc_session::output::validate_crate_name(sess, name, span); - name + (name, origin) }; if let Some(crate_name) = &sess.opts.crate_name { @@ -1069,11 +1070,11 @@ pub fn get_crate_name(sess: &Session, krate_attrs: &[ast::Attribute]) -> Symbol attr_crate_name, }); } - return validate(crate_name, None); + return validate(crate_name, None, CrateNameOrigin::CliOpt); } if let Some((crate_name, span)) = attr_crate_name { - return validate(crate_name, Some(span)); + return validate(crate_name, Some(span), CrateNameOrigin::CrateAttr); } if let Input::File(ref path) = sess.io.input @@ -1082,11 +1083,19 @@ pub fn get_crate_name(sess: &Session, krate_attrs: &[ast::Attribute]) -> Symbol if file_stem.starts_with('-') { sess.dcx().emit_err(errors::CrateNameInvalid { crate_name: file_stem }); } else { - return validate(Symbol::intern(&file_stem.replace('-', "_")), None); + let crate_name = file_stem.replace('-', "_"); + return validate(Symbol::intern(&crate_name), None, CrateNameOrigin::InputFile); } } - Symbol::intern("rust_out") + (Symbol::intern("rust_out"), CrateNameOrigin::Fallback) +} + +pub enum CrateNameOrigin { + CliOpt, + CrateAttr, + InputFile, + Fallback, } fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit { diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index f21922dcb63a8..558c6a86ac6a1 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -1,4 +1,5 @@ use crate::errors; +use crate::passes::CrateNameOrigin; use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; #[cfg(parallel_compiler)] @@ -14,8 +15,9 @@ use rustc_session::{filesearch, EarlyDiagCtxt, Session}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; use rustc_span::source_map::SourceMapInputs; -use rustc_span::symbol::sym; +use rustc_span::{sym, Symbol}; use rustc_target::spec::Target; + use std::env::consts::{DLL_PREFIX, DLL_SUFFIX}; use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicBool, Ordering}; @@ -453,7 +455,11 @@ fn multiple_output_types_to_stdout( } } -pub fn build_output_filenames(attrs: &[ast::Attribute], sess: &Session) -> OutputFilenames { +pub fn build_output_filenames( + sess: &Session, + crate_name: Symbol, + crate_name_origin: CrateNameOrigin, +) -> OutputFilenames { if multiple_output_types_to_stdout( &sess.opts.output_types, sess.io.output_file == Some(OutFileName::Stdout), @@ -461,12 +467,6 @@ pub fn build_output_filenames(attrs: &[ast::Attribute], sess: &Session) -> Outpu sess.dcx().emit_fatal(errors::MultipleOutputTypesToStdout); } - let crate_name = sess - .opts - .crate_name - .clone() - .or_else(|| rustc_attr::find_crate_name(attrs).map(|n| n.to_string())); - match sess.io.output_file { None => { // "-" as input file will cause the parser to read from stdin so we @@ -474,16 +474,22 @@ pub fn build_output_filenames(attrs: &[ast::Attribute], sess: &Session) -> Outpu // We want to toss everything after the final '.' let dirpath = sess.io.output_dir.clone().unwrap_or_default(); - // If a crate name is present, we use it as the link name - let stem = crate_name.clone().unwrap_or_else(|| sess.io.input.filestem().to_owned()); + // FIXME(fmease): Figure out a nicer way to do this. `stem` is almost + // identical to `crate_name` except when it was derived + // from a real(!) input file in which case they may differ + // by `-`/`_` only. + let stem = match crate_name_origin { + CrateNameOrigin::InputFile => sess.io.input.filestem(), + _ => crate_name.as_str(), + }; OutputFilenames::new( dirpath, - crate_name.unwrap_or_else(|| stem.replace('-', "_")), + crate_name, stem, None, sess.io.temps_dir.clone(), - sess.opts.cg.extra_filename.clone(), + &sess.opts.cg.extra_filename, sess.opts.output_types.clone(), ) } @@ -504,15 +510,14 @@ pub fn build_output_filenames(attrs: &[ast::Attribute], sess: &Session) -> Outpu sess.dcx().emit_warn(errors::IgnoringOutDir); } - let out_filestem = - out_file.filestem().unwrap_or_default().to_str().unwrap().to_string(); + let out_filestem = out_file.filestem().unwrap_or_default().to_str().unwrap(); OutputFilenames::new( out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(), - crate_name.unwrap_or_else(|| out_filestem.replace('-', "_")), + crate_name, out_filestem, ofile, sess.io.temps_dir.clone(), - sess.opts.cg.extra_filename.clone(), + &sess.opts.cg.extra_filename, sess.opts.output_types.clone(), ) } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 41c99f7edeeff..46386937d0e24 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -18,7 +18,9 @@ use rustc_feature::UnstableFeatures; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION}; use rustc_span::source_map::FilePathMapping; -use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm}; +use rustc_span::{ + FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm, Symbol, +}; use rustc_target::spec::{FramePointer, LinkSelfContainedComponents, LinkerFeatures}; use rustc_target::spec::{SplitDebuginfo, Target, TargetTriple}; use std::collections::btree_map::{ @@ -945,7 +947,7 @@ impl OutFileName { #[derive(Clone, Hash, Debug, HashStable_Generic, Encodable, Decodable)] pub struct OutputFilenames { pub(crate) out_directory: PathBuf, - /// Crate name. Never contains '-'. + /// Crate name (must not contain `-`) plus extra (`-Cextra-filename`). crate_stem: String, /// Typically based on `.rs` input file name. Any '-' is preserved. filestem: String, @@ -961,11 +963,11 @@ pub const DWARF_OBJECT_EXT: &str = "dwo"; impl OutputFilenames { pub fn new( out_directory: PathBuf, - out_crate_name: String, - out_filestem: String, + crate_name: Symbol, + out_filestem: &str, single_output_file: Option, temps_directory: Option, - extra: String, + extra: &str, outputs: OutputTypes, ) -> Self { OutputFilenames { @@ -973,7 +975,7 @@ impl OutputFilenames { single_output_file, temps_directory, outputs, - crate_stem: format!("{out_crate_name}{extra}"), + crate_stem: format!("{crate_name}{extra}"), filestem: format!("{out_filestem}{extra}"), } }