Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,14 @@ pub fn link_binary(
});

if outputs.outputs.should_link() {
let output = out_filename(sess, crate_type, outputs, crate_info.local_crate_name);
let output = out_filename(sess, crate_type, outputs);
let tmpdir = TempDirBuilder::new()
.prefix("rustc")
.tempdir_in(output.parent().unwrap_or_else(|| Path::new(".")))
.unwrap_or_else(|error| sess.dcx().emit_fatal(errors::CreateTempDir { error }));
let path = MaybeTempDir::new(tmpdir, sess.opts.cg.save_temps);

let crate_name = format!("{}", crate_info.local_crate_name);
let crate_name = format!("{}", sess.crate_name());
let out_filename = output.file_for_writing(
outputs,
OutputType::Exe,
Expand Down Expand Up @@ -2747,12 +2747,8 @@ fn add_order_independent_options(
cmd.optimize();

// Gather the set of NatVis files, if any, and write them out to a temp directory.
let natvis_visualizers = collect_natvis_visualizers(
tmpdir,
sess,
&crate_info.local_crate_name,
&crate_info.natvis_debugger_visualizers,
);
let natvis_visualizers =
collect_natvis_visualizers(tmpdir, sess, &crate_info.natvis_debugger_visualizers);

// Pass debuginfo, NatVis debugger visualizers and strip flags down to the linker.
cmd.debuginfo(sess.opts.cg.strip, &natvis_visualizers);
Expand Down Expand Up @@ -2783,13 +2779,12 @@ fn add_order_independent_options(
fn collect_natvis_visualizers(
tmpdir: &Path,
sess: &Session,
crate_name: &Symbol,
natvis_debugger_visualizers: &BTreeSet<DebuggerVisualizerFile>,
) -> Vec<PathBuf> {
let mut visualizer_paths = Vec::with_capacity(natvis_debugger_visualizers.len());

for (index, visualizer) in natvis_debugger_visualizers.iter().enumerate() {
let visualizer_out_file = tmpdir.join(format!("{}-{}.natvis", crate_name.as_str(), index));
let visualizer_out_file = tmpdir.join(format!("{}-{}.natvis", sess.crate_name(), index));

match fs::write(&visualizer_out_file, &visualizer.src) {
Ok(()) => {
Expand Down
23 changes: 14 additions & 9 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ use rustc_session::config::{
use rustc_session::getopts::{self, Matches};
use rustc_session::lint::{Lint, LintId};
use rustc_session::output::invalid_output_for_target;
use rustc_session::{EarlyDiagCtxt, Session, config};
use rustc_session::{CrateName, EarlyDiagCtxt, Session, config};
use rustc_span::def_id::LOCAL_CRATE;
use rustc_span::{DUMMY_SP, FileName};
use rustc_target::json::ToJson;
Expand Down Expand Up @@ -589,6 +589,12 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) {
};
}
};

// This is the first point at which we have both a Session and the crate name.
let name = CrateName::from_normalized(sess, crate_info.local_crate_name, None);
#[expect(deprecated, reason = "we never previously loaded the crate name")]
sess.crate_name.set(name).expect("-Zlink-only should not build a full TyCtxt");

compiler.codegen_backend.link(sess, compiled_modules, crate_info, metadata, &outputs);
} else {
dcx.emit_fatal(RlinkNotAFile {});
Expand Down Expand Up @@ -683,8 +689,8 @@ 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);
passes::load_crate_name(sess, attrs);
let t_outputs = rustc_interface::util::build_output_filenames(sess);
let crate_types = collect_crate_types(
sess,
&codegen_backend.supported_crate_types(sess),
Expand All @@ -693,9 +699,7 @@ fn print_crate_info(
DUMMY_SP,
);
for &style in &crate_types {
let fname = rustc_session::output::filename_for_input(
sess, style, crate_name, &t_outputs,
);
let fname = rustc_session::output::filename_for_input(sess, style, &t_outputs);
println_info!("{}", fname.as_path().file_name().unwrap().to_string_lossy());
}
}
Expand All @@ -704,16 +708,17 @@ fn print_crate_info(
// no crate attributes, print out an error and exit
return Compilation::Continue;
};
println_info!("{}", passes::get_crate_name(sess, attrs));
passes::load_crate_name(sess, attrs);
println_info!("{}", sess.crate_name());
}
CrateRootLintLevels => {
let Some(attrs) = attrs.as_ref() else {
// no crate attributes, print out an error and exit
return Compilation::Continue;
};
let crate_name = passes::get_crate_name(sess, attrs);
passes::load_crate_name(sess, attrs);
let lint_store = crate::unerased_lint_store(sess);
let features = rustc_expand::config::features(sess, attrs, crate_name);
let features = rustc_expand::config::features(sess, attrs);
let registered_tools =
rustc_resolve::registered_tools_ast(sess.dcx(), attrs, sess, &features);
let lint_levels = rustc_lint::LintLevelsBuilder::crate_root(
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_expand/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ pub struct StripUnconfigured<'a> {
pub lint_node_id: NodeId,
}

pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -> Features {
pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features {
let crate_name = sess.crate_name();
let mut features = Features::default();

if let Some(hir::Attribute::Parsed(AttributeKind::Feature(feature_idents, _))) =
Expand Down
18 changes: 8 additions & 10 deletions compiler/rustc_incremental/src/persist/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ use rustc_data_structures::{base_n, flock};
use rustc_fs_util::{LinkOrCopy, link_or_copy, try_canonicalize};
use rustc_middle::bug;
use rustc_session::{Session, StableCrateId};
use rustc_span::Symbol;
use tracing::debug;

use crate::errors;
Expand Down Expand Up @@ -210,11 +209,7 @@ pub fn in_incr_comp_dir(incr_comp_session_dir: &Path, file_name: &str) -> PathBu
/// The garbage collection will take care of it.
///
/// [`rustc_interface::queries::dep_graph`]: ../../rustc_interface/struct.Queries.html#structfield.dep_graph
pub(crate) fn prepare_session_directory(
sess: &Session,
crate_name: Symbol,
stable_crate_id: StableCrateId,
) {
pub(crate) fn prepare_session_directory(sess: &Session, stable_crate_id: StableCrateId) {
if sess.opts.incremental.is_none() {
return;
}
Expand All @@ -224,7 +219,7 @@ pub(crate) fn prepare_session_directory(
debug!("prepare_session_directory");

// {incr-comp-dir}/{crate-name-and-disambiguator}
let crate_dir = crate_path(sess, crate_name, stable_crate_id);
let crate_dir = crate_path(sess, stable_crate_id);
debug!("crate-dir: {}", crate_dir.display());
create_dir(sess, &crate_dir, "crate");

Expand Down Expand Up @@ -597,11 +592,14 @@ fn string_to_timestamp(s: &str) -> Result<SystemTime, &'static str> {
Ok(UNIX_EPOCH + duration)
}

fn crate_path(sess: &Session, crate_name: Symbol, stable_crate_id: StableCrateId) -> PathBuf {
fn crate_path(sess: &Session, stable_crate_id: StableCrateId) -> PathBuf {
let incr_dir = sess.opts.incremental.as_ref().unwrap().clone();

let crate_name =
format!("{crate_name}-{}", stable_crate_id.as_u64().to_base_fixed_len(CASE_INSENSITIVE));
let crate_name = format!(
"{}-{}",
sess.crate_name(),
stable_crate_id.as_u64().to_base_fixed_len(CASE_INSENSITIVE)
);
incr_dir.join(crate_name)
}

Expand Down
9 changes: 2 additions & 7 deletions compiler/rustc_incremental/src/persist/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use rustc_serialize::Decodable;
use rustc_serialize::opaque::MemDecoder;
use rustc_session::config::IncrementalStateAssertion;
use rustc_session::{Session, StableCrateId};
use rustc_span::Symbol;
use tracing::{debug, warn};

use super::data::*;
Expand Down Expand Up @@ -205,13 +204,9 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache> {

/// Setups the dependency graph by loading an existing graph from disk and set up streaming of a
/// new graph to an incremental session directory.
pub fn setup_dep_graph(
sess: &Session,
crate_name: Symbol,
stable_crate_id: StableCrateId,
) -> DepGraph {
pub fn setup_dep_graph(sess: &Session, stable_crate_id: StableCrateId) -> DepGraph {
// `load_dep_graph` can only be called after `prepare_session_directory`.
prepare_session_directory(sess, crate_name, stable_crate_id);
prepare_session_directory(sess, stable_crate_id);

let res = sess.opts.build_dep_graph().then(|| load_dep_graph(sess));

Expand Down
68 changes: 38 additions & 30 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ use rustc_parse::lexer::StripTokens;
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
use rustc_passes::{abi_test, input_stats, layout_test};
use rustc_resolve::{Resolver, ResolverOutputs};
use rustc_session::Session;
use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType};
use rustc_session::cstore::Untracked;
use rustc_session::output::{filename_for_input, invalid_output_for_target};
use rustc_session::parse::feature_err;
use rustc_session::search_paths::PathKind;
use rustc_session::{CrateName, Session};
use rustc_span::{
DUMMY_SP, ErrorGuaranteed, ExpnKind, SourceFileHash, SourceFileHashAlgorithm, Span, Symbol, sym,
};
Expand Down Expand Up @@ -309,14 +309,13 @@ fn configure_and_expand(
fn print_macro_stats(ecx: &ExtCtxt<'_>) {
use std::fmt::Write;

let crate_name = ecx.ecfg.crate_name.as_str();
let crate_name = if crate_name == "build_script_build" {
let crate_name = if ecx.ecfg.crate_name == sym::build_script_build {
// This is a build script. Get the package name from the environment.
let pkg_name =
std::env::var("CARGO_PKG_NAME").unwrap_or_else(|_| "<unknown crate>".to_string());
format!("{pkg_name} build script")
} else {
crate_name.to_string()
ecx.ecfg.crate_name.to_string()
};

// No instability because we immediately sort the produced vector.
Expand Down Expand Up @@ -508,7 +507,6 @@ fn generated_output_paths(
tcx: TyCtxt<'_>,
outputs: &OutputFilenames,
exact_name: bool,
crate_name: Symbol,
) -> Vec<PathBuf> {
let sess = tcx.sess;
let mut out_filenames = Vec::new();
Expand All @@ -520,7 +518,7 @@ fn generated_output_paths(
// by appending `.rlib`, `.exe`, etc., so we can skip this transformation.
OutputType::Exe if !exact_name => {
for crate_type in tcx.crate_types().iter() {
let p = filename_for_input(sess, *crate_type, crate_name, outputs);
let p = filename_for_input(sess, *crate_type, outputs);
out_filenames.push(p.as_path().to_path_buf());
}
}
Expand Down Expand Up @@ -814,11 +812,9 @@ pub fn write_dep_info(tcx: TyCtxt<'_>) {

let sess = tcx.sess;
let _timer = sess.timer("write_dep_info");
let crate_name = tcx.crate_name(LOCAL_CRATE);

let outputs = tcx.output_filenames(());
let output_paths =
generated_output_paths(tcx, outputs, sess.io.output_file.is_some(), crate_name);
let output_paths = generated_output_paths(tcx, outputs, sess.io.output_file.is_some());

// Ensure the source file isn't accidentally overwritten during compilation.
if let Some(input_path) = sess.io.input.opt_path() {
Expand Down Expand Up @@ -920,7 +916,8 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(

let pre_configured_attrs = rustc_expand::config::pre_configure_attrs(sess, &krate.attrs);

let crate_name = get_crate_name(sess, &pre_configured_attrs);
load_crate_name(sess, &pre_configured_attrs);

let crate_types = collect_crate_types(
sess,
&compiler.codegen_backend.supported_crate_types(sess),
Expand All @@ -929,15 +926,15 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
krate.spans.inner_span,
);
let stable_crate_id = StableCrateId::new(
crate_name,
sess.crate_name(),
crate_types.contains(&CrateType::Executable),
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);

let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id);
let dep_graph = setup_dep_graph(sess, stable_crate_id);

let cstore =
FreezeLock::new(Box::new(CStore::new(compiler.codegen_backend.metadata_loader())) as _);
Expand Down Expand Up @@ -1001,14 +998,12 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
|tcx| {
let feed = tcx.create_crate_num(stable_crate_id).unwrap();
assert_eq!(feed.key(), LOCAL_CRATE);
feed.crate_name(crate_name);
feed.crate_name(sess.crate_name());
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs to stay a query so that it's possible to look up the crate name for other dependent crates.


let feed = tcx.feed_unit_query();
feed.features_query(tcx.arena.alloc(rustc_expand::config::features(
tcx.sess,
&pre_configured_attrs,
crate_name,
)));
feed.features_query(
tcx.arena.alloc(rustc_expand::config::features(tcx.sess, &pre_configured_attrs)),
);
feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
feed.output_filenames(Arc::new(outputs));

Expand Down Expand Up @@ -1257,8 +1252,25 @@ pub(crate) fn start_codegen<'tcx>(
(codegen, crate_info, metadata)
}

/// Compute and validate the crate name.
pub fn get_crate_name(sess: &Session, krate_attrs: &[ast::Attribute]) -> Symbol {
/// Compute and validate the crate name, then store it on the Session.
///
/// NOTE: this function will panic if called more than once in the same Session.
#[expect(deprecated, reason = "initial crate name loading")]
#[track_caller]
pub fn load_crate_name(sess: &Session, krate_attrs: &[ast::Attribute]) {
let new_name = get_crate_name(sess, krate_attrs);

// When we have `--print=file-names,crate-name`, we try to load the crate name more than once.
// Rather than panicking, just allow that as long as we'd use the same name both times.
if let Some(existing) = sess.crate_name.get()
&& *existing == new_name
{
return;
}
sess.crate_name.set(new_name).expect("`load_crate_name` called more than once!");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not that big of a fan of modifying global state.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you see an alternative? I document on the crate_name session option why it's hard to get this before Session construction.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Respecting #![crate_name] in compiler/rustc_metadata/src/locator.rs is just cosmetic and src/tools/miri/src/machine.rs it is not that much of an issue either as miri doesn't have a stable way of invoking it without cargo miri either. For the rest of the places manually passing crate_name like we currently do works fine, right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, if tcx is directly available, then use tcx.crate_name(), otherwise pass crate name from the outside (probably from the same tcx).
tcx is created very early now, almost immediately after pre-configuring crate root attributes and evaluating get_crate_name, so there's a very small window in which the non-approximated crate name is available, but tcx is not.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removing dependencies on TyCtxt that only need the crate name, such as in rustc_attr_parsing

I don't think parsing should depend on knowing the crate name in general, I guess occasionally it may be useful for diagnostics (but need examples), but then it can be passed from the outside as well.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My inclination would also have been to figure out how to have TyCtxt available earlier or do the parts that need the crate name later.

I'd need to do a dive to get the full picture here, but I'm happy to do that and then do some brainstorming session to see what other options we have to make this all nicer

}

fn get_crate_name(sess: &Session, krate_attrs: &[ast::Attribute]) -> CrateName {
// We validate *all* occurrences of `#![crate_name]`, pick the first find and
// if a crate name was passed on the command line via `--crate-name` we enforce
// that they match.
Expand All @@ -1269,11 +1281,7 @@ pub fn get_crate_name(sess: &Session, krate_attrs: &[ast::Attribute]) -> Symbol
let attr_crate_name =
parse_crate_name(sess, krate_attrs, ShouldEmit::EarlyFatal { also_emit_lints: true });

let validate = |name, span| {
rustc_session::output::validate_crate_name(sess, name, span);
name
};

#[expect(deprecated, reason = "sess.crate_name isn't set yet")]
if let Some(crate_name) = &sess.opts.crate_name {
let crate_name = Symbol::intern(crate_name);
if let Some((attr_crate_name, span)) = attr_crate_name
Expand All @@ -1285,11 +1293,11 @@ pub fn get_crate_name(sess: &Session, krate_attrs: &[ast::Attribute]) -> Symbol
attr_crate_name,
});
}
return validate(crate_name, None);
return CrateName::from_normalized(sess, crate_name, None);
}

if let Some((crate_name, span)) = attr_crate_name {
return validate(crate_name, Some(span));
return CrateName::from_normalized(sess, crate_name, Some(span));
}

if let Input::File(ref path) = sess.io.input
Expand All @@ -1298,11 +1306,11 @@ 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);
return CrateName::from_unnormalized(sess, file_stem, None);
}
}

sym::rust_out
CrateName::from_normalized(sess, sym::rust_out, None)
}

pub(crate) fn parse_crate_name(
Expand Down
Loading
Loading