Auto merge of #111345 - jyn514:cfg-release-caching, r=cjgillot,est31
Only depend on CFG_VERSION in rustc_interface This avoids having to rebuild the whole compiler on each commit when `omit-git-hash = false`. cc https://github.com/rust-lang/rust/issues/76720 - this won't fix it, and I'm not suggesting we turn this on by default, but it will make it less painful for people who do have `omit-git-hash` on as a workaround.
This commit is contained in:
commit
c9dc55d05c
24 changed files with 97 additions and 71 deletions
|
@ -23,8 +23,7 @@ use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause};
|
||||||
pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION";
|
pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION";
|
||||||
|
|
||||||
pub fn rust_version_symbol() -> Symbol {
|
pub fn rust_version_symbol() -> Symbol {
|
||||||
let version = option_env!("CFG_VERSION").unwrap_or("<current>");
|
let version = option_env!("CFG_RELEASE").unwrap_or("<current>");
|
||||||
let version = version.split(' ').next().unwrap();
|
|
||||||
Symbol::intern(&version)
|
Symbol::intern(&version)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -806,8 +806,7 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>(
|
||||||
name_in_debuginfo.push(codegen_unit_name);
|
name_in_debuginfo.push(codegen_unit_name);
|
||||||
|
|
||||||
debug!("build_compile_unit_di_node: {:?}", name_in_debuginfo);
|
debug!("build_compile_unit_di_node: {:?}", name_in_debuginfo);
|
||||||
let rustc_producer =
|
let rustc_producer = format!("rustc version {}", tcx.sess.cfg_version);
|
||||||
format!("rustc version {}", option_env!("CFG_VERSION").expect("CFG_VERSION"),);
|
|
||||||
// FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
|
// FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
|
||||||
let producer = format!("clang LLVM ({})", rustc_producer);
|
let producer = format!("clang LLVM ({})", rustc_producer);
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
||||||
use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT};
|
use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT};
|
||||||
use rustc_session::cstore::{self, CrateSource};
|
use rustc_session::cstore::{self, CrateSource};
|
||||||
use rustc_session::utils::NativeLibKind;
|
use rustc_session::utils::NativeLibKind;
|
||||||
|
use rustc_session::Session;
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
use rustc_span::DebuggerVisualizerFile;
|
use rustc_span::DebuggerVisualizerFile;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
@ -175,11 +176,11 @@ pub struct CodegenResults {
|
||||||
pub crate_info: CrateInfo,
|
pub crate_info: CrateInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum CodegenErrors<'a> {
|
pub enum CodegenErrors {
|
||||||
WrongFileType,
|
WrongFileType,
|
||||||
EmptyVersionNumber,
|
EmptyVersionNumber,
|
||||||
EncodingVersionMismatch { version_array: String, rlink_version: u32 },
|
EncodingVersionMismatch { version_array: String, rlink_version: u32 },
|
||||||
RustcVersionMismatch { rustc_version: String, current_version: &'a str },
|
RustcVersionMismatch { rustc_version: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
|
@ -213,10 +214,9 @@ pub fn looks_like_rust_object_file(filename: &str) -> bool {
|
||||||
const RLINK_VERSION: u32 = 1;
|
const RLINK_VERSION: u32 = 1;
|
||||||
const RLINK_MAGIC: &[u8] = b"rustlink";
|
const RLINK_MAGIC: &[u8] = b"rustlink";
|
||||||
|
|
||||||
const RUSTC_VERSION: Option<&str> = option_env!("CFG_VERSION");
|
|
||||||
|
|
||||||
impl CodegenResults {
|
impl CodegenResults {
|
||||||
pub fn serialize_rlink(
|
pub fn serialize_rlink(
|
||||||
|
sess: &Session,
|
||||||
rlink_file: &Path,
|
rlink_file: &Path,
|
||||||
codegen_results: &CodegenResults,
|
codegen_results: &CodegenResults,
|
||||||
) -> Result<usize, io::Error> {
|
) -> Result<usize, io::Error> {
|
||||||
|
@ -225,12 +225,12 @@ impl CodegenResults {
|
||||||
// `emit_raw_bytes` is used to make sure that the version representation does not depend on
|
// `emit_raw_bytes` is used to make sure that the version representation does not depend on
|
||||||
// Encoder's inner representation of `u32`.
|
// Encoder's inner representation of `u32`.
|
||||||
encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes());
|
encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes());
|
||||||
encoder.emit_str(RUSTC_VERSION.unwrap());
|
encoder.emit_str(sess.cfg_version);
|
||||||
Encodable::encode(codegen_results, &mut encoder);
|
Encodable::encode(codegen_results, &mut encoder);
|
||||||
encoder.finish()
|
encoder.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deserialize_rlink<'a>(data: Vec<u8>) -> Result<Self, CodegenErrors<'a>> {
|
pub fn deserialize_rlink(sess: &Session, data: Vec<u8>) -> Result<Self, CodegenErrors> {
|
||||||
// The Decodable machinery is not used here because it panics if the input data is invalid
|
// The Decodable machinery is not used here because it panics if the input data is invalid
|
||||||
// and because its internal representation may change.
|
// and because its internal representation may change.
|
||||||
if !data.starts_with(RLINK_MAGIC) {
|
if !data.starts_with(RLINK_MAGIC) {
|
||||||
|
@ -252,11 +252,9 @@ impl CodegenResults {
|
||||||
|
|
||||||
let mut decoder = MemDecoder::new(&data[4..], 0);
|
let mut decoder = MemDecoder::new(&data[4..], 0);
|
||||||
let rustc_version = decoder.read_str();
|
let rustc_version = decoder.read_str();
|
||||||
let current_version = RUSTC_VERSION.unwrap();
|
if rustc_version != sess.cfg_version {
|
||||||
if rustc_version != current_version {
|
|
||||||
return Err(CodegenErrors::RustcVersionMismatch {
|
return Err(CodegenErrors::RustcVersionMismatch {
|
||||||
rustc_version: rustc_version.to_string(),
|
rustc_version: rustc_version.to_string(),
|
||||||
current_version,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -572,7 +572,7 @@ pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Comp
|
||||||
let rlink_data = fs::read(file).unwrap_or_else(|err| {
|
let rlink_data = fs::read(file).unwrap_or_else(|err| {
|
||||||
sess.emit_fatal(RlinkUnableToRead { err });
|
sess.emit_fatal(RlinkUnableToRead { err });
|
||||||
});
|
});
|
||||||
let codegen_results = match CodegenResults::deserialize_rlink(rlink_data) {
|
let codegen_results = match CodegenResults::deserialize_rlink(sess, rlink_data) {
|
||||||
Ok(codegen) => codegen,
|
Ok(codegen) => codegen,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
match err {
|
match err {
|
||||||
|
@ -586,10 +586,10 @@ pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Comp
|
||||||
rlink_version,
|
rlink_version,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
CodegenErrors::RustcVersionMismatch { rustc_version, current_version } => {
|
CodegenErrors::RustcVersionMismatch { rustc_version } => {
|
||||||
sess.emit_fatal(RLinkRustcVersionMismatch {
|
sess.emit_fatal(RLinkRustcVersionMismatch {
|
||||||
rustc_version,
|
rustc_version,
|
||||||
current_version,
|
current_version: sess.cfg_version,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,13 +10,13 @@ fn def_path_hash_depends_on_crate_id() {
|
||||||
// the crate-id of the defining crate. This is a desirable property
|
// the crate-id of the defining crate. This is a desirable property
|
||||||
// because the crate-id can be more easily changed than the DefPath
|
// because the crate-id can be more easily changed than the DefPath
|
||||||
// of an item, so, in the case of a crate-local DefPathHash collision,
|
// of an item, so, in the case of a crate-local DefPathHash collision,
|
||||||
// the user can simply "role the dice again" for all DefPathHashes in
|
// the user can simply "roll the dice again" for all DefPathHashes in
|
||||||
// the crate by changing the crate disambiguator (e.g. via bumping the
|
// the crate by changing the crate disambiguator (e.g. via bumping the
|
||||||
// crate's version number).
|
// crate's version number).
|
||||||
|
|
||||||
create_session_if_not_set_then(Edition::Edition2024, |_| {
|
create_session_if_not_set_then(Edition::Edition2024, |_| {
|
||||||
let id0 = StableCrateId::new(Symbol::intern("foo"), false, vec!["1".to_string()]);
|
let id0 = StableCrateId::new(Symbol::intern("foo"), false, vec!["1".to_string()], "");
|
||||||
let id1 = StableCrateId::new(Symbol::intern("foo"), false, vec!["2".to_string()]);
|
let id1 = StableCrateId::new(Symbol::intern("foo"), false, vec!["2".to_string()], "");
|
||||||
|
|
||||||
let h0 = mk_test_hash(id0);
|
let h0 = mk_test_hash(id0);
|
||||||
let h1 = mk_test_hash(id1);
|
let h1 = mk_test_hash(id1);
|
||||||
|
|
|
@ -721,7 +721,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// ICE this expression in particular (see #43162).
|
// ICE this expression in particular (see #43162).
|
||||||
if let ExprKind::Path(QPath::Resolved(_, path)) = e.kind {
|
if let ExprKind::Path(QPath::Resolved(_, path)) = e.kind {
|
||||||
if path.segments.len() == 1 && path.segments[0].ident.name == sym::rust {
|
if path.segments.len() == 1 && path.segments[0].ident.name == sym::rust {
|
||||||
fatally_break_rust(self.tcx.sess);
|
fatally_break_rust(self.tcx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,6 @@ use rustc_middle::query::Providers;
|
||||||
use rustc_middle::traits;
|
use rustc_middle::traits;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_session::config;
|
use rustc_session::config;
|
||||||
use rustc_session::Session;
|
|
||||||
use rustc_span::def_id::{DefId, LocalDefId};
|
use rustc_span::def_id::{DefId, LocalDefId};
|
||||||
use rustc_span::{sym, Span};
|
use rustc_span::{sym, Span};
|
||||||
|
|
||||||
|
@ -438,8 +437,8 @@ enum TupleArgumentsFlag {
|
||||||
TupleArguments,
|
TupleArguments,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fatally_break_rust(sess: &Session) {
|
fn fatally_break_rust(tcx: TyCtxt<'_>) {
|
||||||
let handler = sess.diagnostic();
|
let handler = tcx.sess.diagnostic();
|
||||||
handler.span_bug_no_panic(
|
handler.span_bug_no_panic(
|
||||||
MultiSpan::new(),
|
MultiSpan::new(),
|
||||||
"It looks like you're trying to break rust; would you like some ICE?",
|
"It looks like you're trying to break rust; would you like some ICE?",
|
||||||
|
@ -451,7 +450,7 @@ fn fatally_break_rust(sess: &Session) {
|
||||||
);
|
);
|
||||||
handler.note_without_error(format!(
|
handler.note_without_error(format!(
|
||||||
"rustc {} running on {}",
|
"rustc {} running on {}",
|
||||||
option_env!("CFG_VERSION").unwrap_or("unknown_version"),
|
tcx.sess.cfg_version,
|
||||||
config::host_triple(),
|
config::host_triple(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ use rustc_data_structures::memmap::Mmap;
|
||||||
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
|
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
|
||||||
use rustc_serialize::Encoder;
|
use rustc_serialize::Encoder;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::{self, Read};
|
use std::io::{self, Read};
|
||||||
|
@ -25,17 +26,12 @@ const FILE_MAGIC: &[u8] = b"RSIC";
|
||||||
/// Change this if the header format changes.
|
/// Change this if the header format changes.
|
||||||
const HEADER_FORMAT_VERSION: u16 = 0;
|
const HEADER_FORMAT_VERSION: u16 = 0;
|
||||||
|
|
||||||
/// A version string that hopefully is always different for compiler versions
|
pub(crate) fn write_file_header(stream: &mut FileEncoder, sess: &Session) {
|
||||||
/// with different encodings of incremental compilation artifacts. Contains
|
|
||||||
/// the Git commit hash.
|
|
||||||
const RUSTC_VERSION: Option<&str> = option_env!("CFG_VERSION");
|
|
||||||
|
|
||||||
pub(crate) fn write_file_header(stream: &mut FileEncoder, nightly_build: bool) {
|
|
||||||
stream.emit_raw_bytes(FILE_MAGIC);
|
stream.emit_raw_bytes(FILE_MAGIC);
|
||||||
stream
|
stream
|
||||||
.emit_raw_bytes(&[(HEADER_FORMAT_VERSION >> 0) as u8, (HEADER_FORMAT_VERSION >> 8) as u8]);
|
.emit_raw_bytes(&[(HEADER_FORMAT_VERSION >> 0) as u8, (HEADER_FORMAT_VERSION >> 8) as u8]);
|
||||||
|
|
||||||
let rustc_version = rustc_version(nightly_build);
|
let rustc_version = rustc_version(sess.is_nightly_build(), sess.cfg_version);
|
||||||
assert_eq!(rustc_version.len(), (rustc_version.len() as u8) as usize);
|
assert_eq!(rustc_version.len(), (rustc_version.len() as u8) as usize);
|
||||||
stream.emit_raw_bytes(&[rustc_version.len() as u8]);
|
stream.emit_raw_bytes(&[rustc_version.len() as u8]);
|
||||||
stream.emit_raw_bytes(rustc_version.as_bytes());
|
stream.emit_raw_bytes(rustc_version.as_bytes());
|
||||||
|
@ -73,7 +69,7 @@ where
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
write_file_header(&mut encoder, sess.is_nightly_build());
|
write_file_header(&mut encoder, sess);
|
||||||
|
|
||||||
match encode(encoder) {
|
match encode(encoder) {
|
||||||
Ok(position) => {
|
Ok(position) => {
|
||||||
|
@ -100,9 +96,10 @@ where
|
||||||
/// - Returns `Err(..)` if some kind of IO error occurred while reading the
|
/// - Returns `Err(..)` if some kind of IO error occurred while reading the
|
||||||
/// file.
|
/// file.
|
||||||
pub fn read_file(
|
pub fn read_file(
|
||||||
report_incremental_info: bool,
|
|
||||||
path: &Path,
|
path: &Path,
|
||||||
nightly_build: bool,
|
report_incremental_info: bool,
|
||||||
|
is_nightly_build: bool,
|
||||||
|
cfg_version: &'static str,
|
||||||
) -> io::Result<Option<(Mmap, usize)>> {
|
) -> io::Result<Option<(Mmap, usize)>> {
|
||||||
let file = match fs::File::open(path) {
|
let file = match fs::File::open(path) {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
|
@ -152,7 +149,7 @@ pub fn read_file(
|
||||||
let mut buffer = vec![0; rustc_version_str_len];
|
let mut buffer = vec![0; rustc_version_str_len];
|
||||||
file.read_exact(&mut buffer)?;
|
file.read_exact(&mut buffer)?;
|
||||||
|
|
||||||
if buffer != rustc_version(nightly_build).as_bytes() {
|
if buffer != rustc_version(is_nightly_build, cfg_version).as_bytes() {
|
||||||
report_format_mismatch(report_incremental_info, path, "Different compiler version");
|
report_format_mismatch(report_incremental_info, path, "Different compiler version");
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
@ -174,17 +171,15 @@ fn report_format_mismatch(report_incremental_info: bool, file: &Path, message: &
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rustc_version(nightly_build: bool) -> String {
|
/// A version string that hopefully is always different for compiler versions
|
||||||
|
/// with different encodings of incremental compilation artifacts. Contains
|
||||||
|
/// the Git commit hash.
|
||||||
|
fn rustc_version(nightly_build: bool, cfg_version: &'static str) -> Cow<'static, str> {
|
||||||
if nightly_build {
|
if nightly_build {
|
||||||
if let Some(val) = env::var_os("RUSTC_FORCE_RUSTC_VERSION") {
|
if let Ok(val) = env::var("RUSTC_FORCE_RUSTC_VERSION") {
|
||||||
return val.to_string_lossy().into_owned();
|
return val.into();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RUSTC_VERSION
|
cfg_version.into()
|
||||||
.expect(
|
|
||||||
"Cannot use rustc without explicit version for \
|
|
||||||
incremental compilation",
|
|
||||||
)
|
|
||||||
.to_string()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,12 +73,22 @@ impl<T: Default> LoadResult<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_data(
|
fn load_data(path: &Path, sess: &Session) -> LoadResult<(Mmap, usize)> {
|
||||||
report_incremental_info: bool,
|
load_data_no_sess(
|
||||||
|
path,
|
||||||
|
sess.opts.unstable_opts.incremental_info,
|
||||||
|
sess.is_nightly_build(),
|
||||||
|
sess.cfg_version,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_data_no_sess(
|
||||||
path: &Path,
|
path: &Path,
|
||||||
nightly_build: bool,
|
report_incremental_info: bool,
|
||||||
|
is_nightly_build: bool,
|
||||||
|
cfg_version: &'static str,
|
||||||
) -> LoadResult<(Mmap, usize)> {
|
) -> LoadResult<(Mmap, usize)> {
|
||||||
match file_format::read_file(report_incremental_info, path, nightly_build) {
|
match file_format::read_file(path, report_incremental_info, is_nightly_build, cfg_version) {
|
||||||
Ok(Some(data_and_pos)) => LoadResult::Ok { data: data_and_pos },
|
Ok(Some(data_and_pos)) => LoadResult::Ok { data: data_and_pos },
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
// The file either didn't exist or was produced by an incompatible
|
// The file either didn't exist or was produced by an incompatible
|
||||||
|
@ -138,14 +148,13 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
|
||||||
let expected_hash = sess.opts.dep_tracking_hash(false);
|
let expected_hash = sess.opts.dep_tracking_hash(false);
|
||||||
|
|
||||||
let mut prev_work_products = FxHashMap::default();
|
let mut prev_work_products = FxHashMap::default();
|
||||||
let nightly_build = sess.is_nightly_build();
|
|
||||||
|
|
||||||
// If we are only building with -Zquery-dep-graph but without an actual
|
// If we are only building with -Zquery-dep-graph but without an actual
|
||||||
// incr. comp. session directory, we skip this. Otherwise we'd fail
|
// incr. comp. session directory, we skip this. Otherwise we'd fail
|
||||||
// when trying to load work products.
|
// when trying to load work products.
|
||||||
if sess.incr_comp_session_dir_opt().is_some() {
|
if sess.incr_comp_session_dir_opt().is_some() {
|
||||||
let work_products_path = work_products_path(sess);
|
let work_products_path = work_products_path(sess);
|
||||||
let load_result = load_data(report_incremental_info, &work_products_path, nightly_build);
|
let load_result = load_data(&work_products_path, sess);
|
||||||
|
|
||||||
if let LoadResult::Ok { data: (work_products_data, start_pos) } = load_result {
|
if let LoadResult::Ok { data: (work_products_data, start_pos) } = load_result {
|
||||||
// Decode the list of work_products
|
// Decode the list of work_products
|
||||||
|
@ -173,10 +182,13 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let is_nightly_build = sess.is_nightly_build();
|
||||||
|
let cfg_version = sess.cfg_version;
|
||||||
|
|
||||||
MaybeAsync::Async(std::thread::spawn(move || {
|
MaybeAsync::Async(std::thread::spawn(move || {
|
||||||
let _prof_timer = prof.generic_activity("incr_comp_load_dep_graph");
|
let _prof_timer = prof.generic_activity("incr_comp_load_dep_graph");
|
||||||
|
|
||||||
match load_data(report_incremental_info, &path, nightly_build) {
|
match load_data_no_sess(&path, report_incremental_info, is_nightly_build, cfg_version) {
|
||||||
LoadResult::DataOutOfDate => LoadResult::DataOutOfDate,
|
LoadResult::DataOutOfDate => LoadResult::DataOutOfDate,
|
||||||
LoadResult::LoadDepGraph(path, err) => LoadResult::LoadDepGraph(path, err),
|
LoadResult::LoadDepGraph(path, err) => LoadResult::LoadDepGraph(path, err),
|
||||||
LoadResult::DecodeIncrCache(err) => LoadResult::DecodeIncrCache(err),
|
LoadResult::DecodeIncrCache(err) => LoadResult::DecodeIncrCache(err),
|
||||||
|
@ -218,11 +230,7 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache<'_>> {
|
||||||
|
|
||||||
let _prof_timer = sess.prof.generic_activity("incr_comp_load_query_result_cache");
|
let _prof_timer = sess.prof.generic_activity("incr_comp_load_query_result_cache");
|
||||||
|
|
||||||
match load_data(
|
match load_data(&query_cache_path(sess), sess) {
|
||||||
sess.opts.unstable_opts.incremental_info,
|
|
||||||
&query_cache_path(sess),
|
|
||||||
sess.is_nightly_build(),
|
|
||||||
) {
|
|
||||||
LoadResult::Ok { data: (bytes, start_pos) } => {
|
LoadResult::Ok { data: (bytes, start_pos) } => {
|
||||||
Some(OnDiskCache::new(sess, bytes, start_pos))
|
Some(OnDiskCache::new(sess, bytes, start_pos))
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,7 +164,7 @@ pub fn build_dep_graph(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
file_format::write_file_header(&mut encoder, sess.is_nightly_build());
|
file_format::write_file_header(&mut encoder, sess);
|
||||||
|
|
||||||
// First encode the commandline arguments hash
|
// First encode the commandline arguments hash
|
||||||
sess.opts.dep_tracking_hash(false).encode(&mut encoder);
|
sess.opts.dep_tracking_hash(false).encode(&mut encoder);
|
||||||
|
|
|
@ -89,6 +89,7 @@ pub fn register_plugins<'a>(
|
||||||
crate_name,
|
crate_name,
|
||||||
sess.crate_types().contains(&CrateType::Executable),
|
sess.crate_types().contains(&CrateType::Executable),
|
||||||
sess.opts.cg.metadata.clone(),
|
sess.opts.cg.metadata.clone(),
|
||||||
|
sess.cfg_version,
|
||||||
);
|
);
|
||||||
sess.stable_crate_id.set(stable_crate_id).expect("not yet initialized");
|
sess.stable_crate_id.set(stable_crate_id).expect("not yet initialized");
|
||||||
rustc_incremental::prepare_session_directory(sess, crate_name, stable_crate_id)?;
|
rustc_incremental::prepare_session_directory(sess, crate_name, stable_crate_id)?;
|
||||||
|
|
|
@ -369,7 +369,7 @@ impl Linker {
|
||||||
|
|
||||||
if sess.opts.unstable_opts.no_link {
|
if sess.opts.unstable_opts.no_link {
|
||||||
let rlink_file = self.prepare_outputs.with_extension(config::RLINK_EXT);
|
let rlink_file = self.prepare_outputs.with_extension(config::RLINK_EXT);
|
||||||
CodegenResults::serialize_rlink(&rlink_file, &codegen_results)
|
CodegenResults::serialize_rlink(sess, &rlink_file, &codegen_results)
|
||||||
.map_err(|error| sess.emit_fatal(FailedWritingFile { path: &rlink_file, error }))?;
|
.map_err(|error| sess.emit_fatal(FailedWritingFile { path: &rlink_file, error }))?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,8 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
|
||||||
output_file: None,
|
output_file: None,
|
||||||
temps_dir,
|
temps_dir,
|
||||||
};
|
};
|
||||||
let sess = build_session(sessopts, io, None, registry, vec![], Default::default(), None, None);
|
let sess =
|
||||||
|
build_session(sessopts, io, None, registry, vec![], Default::default(), None, None, "");
|
||||||
(sess, cfg)
|
(sess, cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,7 @@ pub fn create_session(
|
||||||
lint_caps,
|
lint_caps,
|
||||||
file_loader,
|
file_loader,
|
||||||
target_override,
|
target_override,
|
||||||
|
rustc_version_str().unwrap_or("unknown"),
|
||||||
);
|
);
|
||||||
|
|
||||||
codegen_backend.init(&sess);
|
codegen_backend.init(&sess);
|
||||||
|
|
|
@ -245,6 +245,7 @@ pub(crate) struct CrateLocator<'a> {
|
||||||
only_needs_metadata: bool,
|
only_needs_metadata: bool,
|
||||||
sysroot: &'a Path,
|
sysroot: &'a Path,
|
||||||
metadata_loader: &'a dyn MetadataLoader,
|
metadata_loader: &'a dyn MetadataLoader,
|
||||||
|
cfg_version: &'static str,
|
||||||
|
|
||||||
// Immutable per-search configuration.
|
// Immutable per-search configuration.
|
||||||
crate_name: Symbol,
|
crate_name: Symbol,
|
||||||
|
@ -322,6 +323,7 @@ impl<'a> CrateLocator<'a> {
|
||||||
only_needs_metadata,
|
only_needs_metadata,
|
||||||
sysroot: &sess.sysroot,
|
sysroot: &sess.sysroot,
|
||||||
metadata_loader,
|
metadata_loader,
|
||||||
|
cfg_version: sess.cfg_version,
|
||||||
crate_name,
|
crate_name,
|
||||||
exact_paths: if hash.is_none() {
|
exact_paths: if hash.is_none() {
|
||||||
sess.opts
|
sess.opts
|
||||||
|
@ -654,7 +656,7 @@ impl<'a> CrateLocator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn crate_matches(&mut self, metadata: &MetadataBlob, libpath: &Path) -> Option<Svh> {
|
fn crate_matches(&mut self, metadata: &MetadataBlob, libpath: &Path) -> Option<Svh> {
|
||||||
let rustc_version = rustc_version();
|
let rustc_version = rustc_version(self.cfg_version);
|
||||||
let found_version = metadata.get_rustc_version();
|
let found_version = metadata.get_rustc_version();
|
||||||
if found_version != rustc_version {
|
if found_version != rustc_version {
|
||||||
info!("Rejecting via version: expected {} got {}", rustc_version, found_version);
|
info!("Rejecting via version: expected {} got {}", rustc_version, found_version);
|
||||||
|
@ -1096,7 +1098,7 @@ impl CrateError {
|
||||||
crate_name,
|
crate_name,
|
||||||
add_info,
|
add_info,
|
||||||
found_crates,
|
found_crates,
|
||||||
rustc_version: rustc_version(),
|
rustc_version: rustc_version(sess.cfg_version),
|
||||||
});
|
});
|
||||||
} else if !locator.crate_rejections.via_invalid.is_empty() {
|
} else if !locator.crate_rejections.via_invalid.is_empty() {
|
||||||
let mut crate_rejections = Vec::new();
|
let mut crate_rejections = Vec::new();
|
||||||
|
|
|
@ -2276,7 +2276,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Encode the rustc version string in a predictable location.
|
// Encode the rustc version string in a predictable location.
|
||||||
rustc_version().encode(&mut ecx);
|
rustc_version(tcx.sess.cfg_version).encode(&mut ecx);
|
||||||
|
|
||||||
// Encode all the entries and extra information in the crate,
|
// Encode all the entries and extra information in the crate,
|
||||||
// culminating in the `CrateRoot` which points to all of it.
|
// culminating in the `CrateRoot` which points to all of it.
|
||||||
|
|
|
@ -48,8 +48,8 @@ mod def_path_hash_map;
|
||||||
mod encoder;
|
mod encoder;
|
||||||
mod table;
|
mod table;
|
||||||
|
|
||||||
pub(crate) fn rustc_version() -> String {
|
pub(crate) fn rustc_version(cfg_version: &'static str) -> String {
|
||||||
format!("rustc {}", option_env!("CFG_VERSION").unwrap_or("unknown version"))
|
format!("rustc {}", cfg_version)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Metadata encoding version.
|
/// Metadata encoding version.
|
||||||
|
|
|
@ -28,7 +28,7 @@ pub fn erase<T: EraseType>(src: T) -> Erase<T> {
|
||||||
};
|
};
|
||||||
|
|
||||||
Erased::<<T as EraseType>::Result> {
|
Erased::<<T as EraseType>::Result> {
|
||||||
// SAFETY: Is it safe to transmute to MaybeUninit for types with the same sizes.
|
// SAFETY: It is safe to transmute to MaybeUninit for types with the same sizes.
|
||||||
data: unsafe { transmute_copy(&src) },
|
data: unsafe { transmute_copy(&src) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,6 +211,9 @@ pub struct Session {
|
||||||
|
|
||||||
/// Set of enabled features for the current target, including unstable ones.
|
/// Set of enabled features for the current target, including unstable ones.
|
||||||
pub unstable_target_features: FxIndexSet<Symbol>,
|
pub unstable_target_features: FxIndexSet<Symbol>,
|
||||||
|
|
||||||
|
/// The version of the rustc process, possibly including a commit hash and description.
|
||||||
|
pub cfg_version: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PerfStats {
|
pub struct PerfStats {
|
||||||
|
@ -1366,6 +1369,7 @@ pub fn build_session(
|
||||||
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
|
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
|
||||||
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
|
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
|
||||||
target_override: Option<Target>,
|
target_override: Option<Target>,
|
||||||
|
cfg_version: &'static str,
|
||||||
) -> Session {
|
) -> Session {
|
||||||
// FIXME: This is not general enough to make the warning lint completely override
|
// FIXME: This is not general enough to make the warning lint completely override
|
||||||
// normal diagnostic warnings, since the warning lint can also be denied and changed
|
// normal diagnostic warnings, since the warning lint can also be denied and changed
|
||||||
|
@ -1510,6 +1514,7 @@ pub fn build_session(
|
||||||
asm_arch,
|
asm_arch,
|
||||||
target_features: Default::default(),
|
target_features: Default::default(),
|
||||||
unstable_target_features: Default::default(),
|
unstable_target_features: Default::default(),
|
||||||
|
cfg_version,
|
||||||
};
|
};
|
||||||
|
|
||||||
validate_commandline_args_with_session_available(&sess);
|
validate_commandline_args_with_session_available(&sess);
|
||||||
|
|
|
@ -146,7 +146,12 @@ pub struct StableCrateId(pub(crate) Hash64);
|
||||||
impl StableCrateId {
|
impl StableCrateId {
|
||||||
/// Computes the stable ID for a crate with the given name and
|
/// Computes the stable ID for a crate with the given name and
|
||||||
/// `-Cmetadata` arguments.
|
/// `-Cmetadata` arguments.
|
||||||
pub fn new(crate_name: Symbol, is_exe: bool, mut metadata: Vec<String>) -> StableCrateId {
|
pub fn new(
|
||||||
|
crate_name: Symbol,
|
||||||
|
is_exe: bool,
|
||||||
|
mut metadata: Vec<String>,
|
||||||
|
cfg_version: &'static str,
|
||||||
|
) -> StableCrateId {
|
||||||
let mut hasher = StableHasher::new();
|
let mut hasher = StableHasher::new();
|
||||||
// We must hash the string text of the crate name, not the id, as the id is not stable
|
// We must hash the string text of the crate name, not the id, as the id is not stable
|
||||||
// across builds.
|
// across builds.
|
||||||
|
@ -180,7 +185,7 @@ impl StableCrateId {
|
||||||
if let Some(val) = std::env::var_os("RUSTC_FORCE_RUSTC_VERSION") {
|
if let Some(val) = std::env::var_os("RUSTC_FORCE_RUSTC_VERSION") {
|
||||||
hasher.write(val.to_string_lossy().into_owned().as_bytes())
|
hasher.write(val.to_string_lossy().into_owned().as_bytes())
|
||||||
} else {
|
} else {
|
||||||
hasher.write(option_env!("CFG_VERSION").unwrap_or("unknown version").as_bytes());
|
hasher.write(cfg_version.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
StableCrateId(hasher.finish())
|
StableCrateId(hasher.finish())
|
||||||
|
|
|
@ -8,15 +8,13 @@ fn main() {
|
||||||
let version_path = root_path.join("src").join("version");
|
let version_path = root_path.join("src").join("version");
|
||||||
let version_str = t!(std::fs::read_to_string(&version_path), version_path);
|
let version_str = t!(std::fs::read_to_string(&version_path), version_path);
|
||||||
let version_str = version_str.trim();
|
let version_str = version_str.trim();
|
||||||
walk::walk(
|
walk::walk_many(
|
||||||
&root_path,
|
&[&root_path.join("compiler"), &root_path.join("library")],
|
||||||
|path, _is_dir| {
|
|path, _is_dir| {
|
||||||
walk::filter_dirs(path)
|
walk::filter_dirs(path)
|
||||||
// We exempt these as they require the placeholder
|
// We exempt these as they require the placeholder
|
||||||
// for their operation
|
// for their operation
|
||||||
|| path.ends_with("compiler/rustc_attr/src/builtin.rs")
|
|| path.ends_with("compiler/rustc_attr/src/builtin.rs")
|
||||||
|| path.ends_with("src/tools/tidy/src/features/version.rs")
|
|
||||||
|| path.ends_with("src/tools/replace-version-placeholder")
|
|
||||||
},
|
},
|
||||||
&mut |entry, contents| {
|
&mut |entry, contents| {
|
||||||
if !contents.contains(VERSION_PLACEHOLDER) {
|
if !contents.contains(VERSION_PLACEHOLDER) {
|
||||||
|
|
6
tests/run-make/CURRENT_RUSTC_VERSION/Makefile
Normal file
6
tests/run-make/CURRENT_RUSTC_VERSION/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
include ../tools.mk
|
||||||
|
|
||||||
|
all:
|
||||||
|
$(RUSTC) --emit=metadata --crate-type lib stable.rs
|
||||||
|
$(RUSTC) --emit=metadata --extern stable=$(TMPDIR)/libstable.rmeta main.rs 2>&1 >/dev/null \
|
||||||
|
| $(CGREP) -e "stable since $$(cat $(S)/src/version)(-[a-zA-Z]+)?"
|
4
tests/run-make/CURRENT_RUSTC_VERSION/main.rs
Normal file
4
tests/run-make/CURRENT_RUSTC_VERSION/main.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#![feature(foo)]
|
||||||
|
extern crate stable;
|
||||||
|
|
||||||
|
fn main() {}
|
5
tests/run-make/CURRENT_RUSTC_VERSION/stable.rs
Normal file
5
tests/run-make/CURRENT_RUSTC_VERSION/stable.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#![feature(staged_api)]
|
||||||
|
#![stable(since = "1.0.0", feature = "rust1")]
|
||||||
|
|
||||||
|
#[stable(since = "CURRENT_RUSTC_VERSION", feature = "foo")]
|
||||||
|
pub fn foo() {}
|
Loading…
Add table
Add a link
Reference in a new issue