mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Rollup merge of #154449 - nnethercote:rustc_errors-dep-rustc_abi, r=davidtwco
Invert dependency between `rustc_errors` and `rustc_abi`. Currently, `rustc_errors` depends on `rustc_abi`, which depends on `rustc_error_messages`. This is a bit odd. `rustc_errors` depends on `rustc_abi` for a single reason: `rustc_abi` defines a type `TargetDataLayoutErrors` and `rustc_errors` impls `Diagnostic` for that type. We can get a more natural relationship by inverting the dependency, moving the `Diagnostic` trait upstream. Then `rustc_abi` defines `TargetDataLayoutErrors` and also impls `Diagnostic` for it. `rustc_errors` is already pretty far upstream in the crate graph, it doesn't hurt to push it a little further because errors are a very low-level concept. r? @davidtwco
This commit is contained in:
+1
-1
@@ -3505,6 +3505,7 @@ dependencies = [
|
||||
"rand_xoshiro",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_messages",
|
||||
"rustc_errors",
|
||||
"rustc_hashes",
|
||||
"rustc_index",
|
||||
"rustc_macros",
|
||||
@@ -3909,7 +3910,6 @@ dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"derive_setters",
|
||||
"rustc_abi",
|
||||
"rustc_ast",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
|
||||
@@ -10,6 +10,7 @@ rand = { version = "0.9.0", default-features = false, optional = true }
|
||||
rand_xoshiro = { version = "0.7.0", optional = true }
|
||||
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
|
||||
rustc_error_messages = { path = "../rustc_error_messages", optional = true }
|
||||
rustc_errors = { path = "../rustc_errors", optional = true }
|
||||
rustc_hashes = { path = "../rustc_hashes" }
|
||||
rustc_index = { path = "../rustc_index", default-features = false }
|
||||
rustc_macros = { path = "../rustc_macros", optional = true }
|
||||
@@ -21,11 +22,12 @@ tracing = "0.1"
|
||||
[features]
|
||||
# tidy-alphabetical-start
|
||||
default = ["nightly", "randomize"]
|
||||
# rust-analyzer depends on this crate and we therefore require it to built on a stable toolchain
|
||||
# without depending on rustc_data_structures, rustc_macros and rustc_serialize
|
||||
# rust-analyzer depends on this crate and we therefore require it to build on a stable toolchain
|
||||
# without depending on the rustc_* crates in the following list.
|
||||
nightly = [
|
||||
"dep:rustc_data_structures",
|
||||
"dep:rustc_error_messages",
|
||||
"dep:rustc_errors",
|
||||
"dep:rustc_macros",
|
||||
"dep:rustc_serialize",
|
||||
"dep:rustc_span",
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
use bitflags::bitflags;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_data_structures::stable_hasher::StableOrd;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, msg};
|
||||
use rustc_hashes::Hash64;
|
||||
use rustc_index::{Idx, IndexSlice, IndexVec};
|
||||
#[cfg(feature = "nightly")]
|
||||
@@ -332,7 +334,7 @@ fn default() -> TargetDataLayout {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum TargetDataLayoutErrors<'a> {
|
||||
pub enum TargetDataLayoutError<'a> {
|
||||
InvalidAddressSpace { addr_space: &'a str, cause: &'a str, err: ParseIntError },
|
||||
InvalidBits { kind: &'a str, bit: &'a str, cause: &'a str, err: ParseIntError },
|
||||
MissingAlignment { cause: &'a str },
|
||||
@@ -343,6 +345,51 @@ pub enum TargetDataLayoutErrors<'a> {
|
||||
UnknownPointerSpecification { err: String },
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetDataLayoutError<'_> {
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
|
||||
match self {
|
||||
TargetDataLayoutError::InvalidAddressSpace { addr_space, err, cause } => {
|
||||
Diag::new(dcx, level, msg!("invalid address space `{$addr_space}` for `{$cause}` in \"data-layout\": {$err}"))
|
||||
.with_arg("addr_space", addr_space)
|
||||
.with_arg("cause", cause)
|
||||
.with_arg("err", err)
|
||||
}
|
||||
TargetDataLayoutError::InvalidBits { kind, bit, cause, err } => {
|
||||
Diag::new(dcx, level, msg!("invalid {$kind} `{$bit}` for `{$cause}` in \"data-layout\": {$err}"))
|
||||
.with_arg("kind", kind)
|
||||
.with_arg("bit", bit)
|
||||
.with_arg("cause", cause)
|
||||
.with_arg("err", err)
|
||||
}
|
||||
TargetDataLayoutError::MissingAlignment { cause } => {
|
||||
Diag::new(dcx, level, msg!("missing alignment for `{$cause}` in \"data-layout\""))
|
||||
.with_arg("cause", cause)
|
||||
}
|
||||
TargetDataLayoutError::InvalidAlignment { cause, err } => {
|
||||
Diag::new(dcx, level, msg!("invalid alignment for `{$cause}` in \"data-layout\": {$err}"))
|
||||
.with_arg("cause", cause)
|
||||
.with_arg("err", err.to_string())
|
||||
}
|
||||
TargetDataLayoutError::InconsistentTargetArchitecture { dl, target } => {
|
||||
Diag::new(dcx, level, msg!("inconsistent target specification: \"data-layout\" claims architecture is {$dl}-endian, while \"target-endian\" is `{$target}`"))
|
||||
.with_arg("dl", dl).with_arg("target", target)
|
||||
}
|
||||
TargetDataLayoutError::InconsistentTargetPointerWidth { pointer_size, target } => {
|
||||
Diag::new(dcx, level, msg!("inconsistent target specification: \"data-layout\" claims pointers are {$pointer_size}-bit, while \"target-pointer-width\" is `{$target}`"))
|
||||
.with_arg("pointer_size", pointer_size).with_arg("target", target)
|
||||
}
|
||||
TargetDataLayoutError::InvalidBitsSize { err } => {
|
||||
Diag::new(dcx, level, msg!("{$err}")).with_arg("err", err)
|
||||
}
|
||||
TargetDataLayoutError::UnknownPointerSpecification { err } => {
|
||||
Diag::new(dcx, level, msg!("unknown pointer specification `{$err}` in datalayout string"))
|
||||
.with_arg("err", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TargetDataLayout {
|
||||
/// Parse data layout from an
|
||||
/// [llvm data layout string](https://llvm.org/docs/LangRef.html#data-layout)
|
||||
@@ -352,17 +399,17 @@ impl TargetDataLayout {
|
||||
pub fn parse_from_llvm_datalayout_string<'a>(
|
||||
input: &'a str,
|
||||
default_address_space: AddressSpace,
|
||||
) -> Result<TargetDataLayout, TargetDataLayoutErrors<'a>> {
|
||||
) -> Result<TargetDataLayout, TargetDataLayoutError<'a>> {
|
||||
// Parse an address space index from a string.
|
||||
let parse_address_space = |s: &'a str, cause: &'a str| {
|
||||
s.parse::<u32>().map(AddressSpace).map_err(|err| {
|
||||
TargetDataLayoutErrors::InvalidAddressSpace { addr_space: s, cause, err }
|
||||
TargetDataLayoutError::InvalidAddressSpace { addr_space: s, cause, err }
|
||||
})
|
||||
};
|
||||
|
||||
// Parse a bit count from a string.
|
||||
let parse_bits = |s: &'a str, kind: &'a str, cause: &'a str| {
|
||||
s.parse::<u64>().map_err(|err| TargetDataLayoutErrors::InvalidBits {
|
||||
s.parse::<u64>().map_err(|err| TargetDataLayoutError::InvalidBits {
|
||||
kind,
|
||||
bit: s,
|
||||
cause,
|
||||
@@ -378,7 +425,7 @@ pub fn parse_from_llvm_datalayout_string<'a>(
|
||||
let parse_align_str = |s: &'a str, cause: &'a str| {
|
||||
let align_from_bits = |bits| {
|
||||
Align::from_bits(bits)
|
||||
.map_err(|err| TargetDataLayoutErrors::InvalidAlignment { cause, err })
|
||||
.map_err(|err| TargetDataLayoutError::InvalidAlignment { cause, err })
|
||||
};
|
||||
let abi = parse_bits(s, "alignment", cause)?;
|
||||
Ok(align_from_bits(abi)?)
|
||||
@@ -388,7 +435,7 @@ pub fn parse_from_llvm_datalayout_string<'a>(
|
||||
// ignoring the secondary alignment specifications.
|
||||
let parse_align_seq = |s: &[&'a str], cause: &'a str| {
|
||||
if s.is_empty() {
|
||||
return Err(TargetDataLayoutErrors::MissingAlignment { cause });
|
||||
return Err(TargetDataLayoutError::MissingAlignment { cause });
|
||||
}
|
||||
parse_align_str(s[0], cause)
|
||||
};
|
||||
@@ -426,7 +473,7 @@ pub fn parse_from_llvm_datalayout_string<'a>(
|
||||
// However, we currently don't take into account further specifications:
|
||||
// an error is emitted instead.
|
||||
if p.starts_with(char::is_alphabetic) {
|
||||
return Err(TargetDataLayoutErrors::UnknownPointerSpecification {
|
||||
return Err(TargetDataLayoutError::UnknownPointerSpecification {
|
||||
err: p.to_string(),
|
||||
});
|
||||
}
|
||||
@@ -471,7 +518,7 @@ pub fn parse_from_llvm_datalayout_string<'a>(
|
||||
// However, we currently don't take into account further specifications:
|
||||
// an error is emitted instead.
|
||||
if p.starts_with(char::is_alphabetic) {
|
||||
return Err(TargetDataLayoutErrors::UnknownPointerSpecification {
|
||||
return Err(TargetDataLayoutError::UnknownPointerSpecification {
|
||||
err: p.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -256,7 +256,7 @@ pub struct CompiledModules {
|
||||
pub allocator_module: Option<CompiledModule>,
|
||||
}
|
||||
|
||||
pub enum CodegenErrors {
|
||||
pub enum CodegenError {
|
||||
WrongFileType,
|
||||
EmptyVersionNumber,
|
||||
EncodingVersionMismatch { version_array: String, rlink_version: u32 },
|
||||
@@ -317,32 +317,32 @@ pub fn serialize_rlink(
|
||||
pub fn deserialize_rlink(
|
||||
sess: &Session,
|
||||
data: Vec<u8>,
|
||||
) -> Result<(Self, CrateInfo, EncodedMetadata, OutputFilenames), CodegenErrors> {
|
||||
) -> Result<(Self, CrateInfo, EncodedMetadata, OutputFilenames), CodegenError> {
|
||||
// The Decodable machinery is not used here because it panics if the input data is invalid
|
||||
// and because its internal representation may change.
|
||||
if !data.starts_with(RLINK_MAGIC) {
|
||||
return Err(CodegenErrors::WrongFileType);
|
||||
return Err(CodegenError::WrongFileType);
|
||||
}
|
||||
let data = &data[RLINK_MAGIC.len()..];
|
||||
if data.len() < 4 {
|
||||
return Err(CodegenErrors::EmptyVersionNumber);
|
||||
return Err(CodegenError::EmptyVersionNumber);
|
||||
}
|
||||
|
||||
let mut version_array: [u8; 4] = Default::default();
|
||||
version_array.copy_from_slice(&data[..4]);
|
||||
if u32::from_be_bytes(version_array) != RLINK_VERSION {
|
||||
return Err(CodegenErrors::EncodingVersionMismatch {
|
||||
return Err(CodegenError::EncodingVersionMismatch {
|
||||
version_array: String::from_utf8_lossy(&version_array).to_string(),
|
||||
rlink_version: RLINK_VERSION,
|
||||
});
|
||||
}
|
||||
|
||||
let Ok(mut decoder) = MemDecoder::new(&data[4..], 0) else {
|
||||
return Err(CodegenErrors::CorruptFile);
|
||||
return Err(CodegenError::CorruptFile);
|
||||
};
|
||||
let rustc_version = decoder.read_str();
|
||||
if rustc_version != sess.cfg_version {
|
||||
return Err(CodegenErrors::RustcVersionMismatch {
|
||||
return Err(CodegenError::RustcVersionMismatch {
|
||||
rustc_version: rustc_version.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_codegen_ssa::traits::CodegenBackend;
|
||||
use rustc_codegen_ssa::{CodegenErrors, CompiledModules};
|
||||
use rustc_codegen_ssa::{CodegenError, CompiledModules};
|
||||
use rustc_data_structures::profiling::{
|
||||
TimePassesFormat, get_resident_set_size, print_time_passes_entry,
|
||||
};
|
||||
@@ -567,23 +567,21 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) {
|
||||
}
|
||||
Err(err) => {
|
||||
match err {
|
||||
CodegenErrors::WrongFileType => dcx.emit_fatal(RLinkWrongFileType),
|
||||
CodegenErrors::EmptyVersionNumber => {
|
||||
dcx.emit_fatal(RLinkEmptyVersionNumber)
|
||||
}
|
||||
CodegenErrors::EncodingVersionMismatch { version_array, rlink_version } => {
|
||||
CodegenError::WrongFileType => dcx.emit_fatal(RLinkWrongFileType),
|
||||
CodegenError::EmptyVersionNumber => dcx.emit_fatal(RLinkEmptyVersionNumber),
|
||||
CodegenError::EncodingVersionMismatch { version_array, rlink_version } => {
|
||||
dcx.emit_fatal(RLinkEncodingVersionMismatch {
|
||||
version_array,
|
||||
rlink_version,
|
||||
})
|
||||
}
|
||||
CodegenErrors::RustcVersionMismatch { rustc_version } => {
|
||||
CodegenError::RustcVersionMismatch { rustc_version } => {
|
||||
dcx.emit_fatal(RLinkRustcVersionMismatch {
|
||||
rustc_version,
|
||||
current_version: sess.cfg_version,
|
||||
})
|
||||
}
|
||||
CodegenErrors::CorruptFile => {
|
||||
CodegenError::CorruptFile => {
|
||||
dcx.emit_fatal(RlinkCorruptFile { file });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,7 +9,6 @@ annotate-snippets = { version = "0.12.15", features = ["simd"] }
|
||||
anstream = "0.6.20"
|
||||
anstyle = "1.0.13"
|
||||
derive_setters = "0.1.6"
|
||||
rustc_abi = { path = "../rustc_abi" }
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_error_codes = { path = "../rustc_error_codes" }
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use rustc_abi::TargetDataLayoutErrors;
|
||||
use rustc_error_messages::{DiagArgValue, IntoDiagArg};
|
||||
use rustc_macros::Subdiagnostic;
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
use crate::diagnostic::DiagLocation;
|
||||
use crate::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, Subdiagnostic, msg};
|
||||
use crate::{Diag, EmissionGuarantee, Subdiagnostic};
|
||||
|
||||
impl IntoDiagArg for DiagLocation {
|
||||
fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
|
||||
@@ -37,55 +36,6 @@ fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetDataLayoutErrors<'_> {
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
|
||||
match self {
|
||||
TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => {
|
||||
Diag::new(dcx, level, msg!("invalid address space `{$addr_space}` for `{$cause}` in \"data-layout\": {$err}"))
|
||||
.with_arg("addr_space", addr_space)
|
||||
.with_arg("cause", cause)
|
||||
.with_arg("err", err)
|
||||
}
|
||||
TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => {
|
||||
Diag::new(dcx, level, msg!("invalid {$kind} `{$bit}` for `{$cause}` in \"data-layout\": {$err}"))
|
||||
.with_arg("kind", kind)
|
||||
.with_arg("bit", bit)
|
||||
.with_arg("cause", cause)
|
||||
.with_arg("err", err)
|
||||
}
|
||||
TargetDataLayoutErrors::MissingAlignment { cause } => {
|
||||
Diag::new(dcx, level, msg!("missing alignment for `{$cause}` in \"data-layout\""))
|
||||
.with_arg("cause", cause)
|
||||
}
|
||||
TargetDataLayoutErrors::InvalidAlignment { cause, err } => {
|
||||
Diag::new(dcx, level, msg!(
|
||||
"invalid alignment for `{$cause}` in \"data-layout\": {$err}"
|
||||
))
|
||||
.with_arg("cause", cause)
|
||||
.with_arg("err", err.to_string())
|
||||
}
|
||||
TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
|
||||
Diag::new(dcx, level, msg!(
|
||||
"inconsistent target specification: \"data-layout\" claims architecture is {$dl}-endian, while \"target-endian\" is `{$target}`"
|
||||
))
|
||||
.with_arg("dl", dl).with_arg("target", target)
|
||||
}
|
||||
TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => {
|
||||
Diag::new(dcx, level, msg!(
|
||||
"inconsistent target specification: \"data-layout\" claims pointers are {$pointer_size}-bit, while \"target-pointer-width\" is `{$target}`"
|
||||
)).with_arg("pointer_size", pointer_size).with_arg("target", target)
|
||||
}
|
||||
TargetDataLayoutErrors::InvalidBitsSize { err } => {
|
||||
Diag::new(dcx, level, msg!("{$err}")).with_arg("err", err)
|
||||
}
|
||||
TargetDataLayoutErrors::UnknownPointerSpecification { err } => {
|
||||
Diag::new(dcx, level, msg!("unknown pointer specification `{$err}` in datalayout string"))
|
||||
.with_arg("err", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Utility struct used to apply a single label while highlighting multiple spans
|
||||
pub struct SingleLabelManySpans {
|
||||
pub spans: Vec<Span>,
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
use std::{fmt, io};
|
||||
|
||||
use rustc_abi::{
|
||||
Align, CanonAbi, Endian, ExternAbi, Integer, Size, TargetDataLayout, TargetDataLayoutErrors,
|
||||
Align, CanonAbi, Endian, ExternAbi, Integer, Size, TargetDataLayout, TargetDataLayoutError,
|
||||
};
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
|
||||
use rustc_error_messages::{DiagArgValue, IntoDiagArg, into_diag_arg_using_display};
|
||||
@@ -2166,7 +2166,7 @@ pub struct TargetMetadata {
|
||||
}
|
||||
|
||||
impl Target {
|
||||
pub fn parse_data_layout(&self) -> Result<TargetDataLayout, TargetDataLayoutErrors<'_>> {
|
||||
pub fn parse_data_layout(&self) -> Result<TargetDataLayout, TargetDataLayoutError<'_>> {
|
||||
let mut dl = TargetDataLayout::parse_from_llvm_datalayout_string(
|
||||
&self.data_layout,
|
||||
self.options.default_address_space,
|
||||
@@ -2174,7 +2174,7 @@ pub fn parse_data_layout(&self) -> Result<TargetDataLayout, TargetDataLayoutErro
|
||||
|
||||
// Perform consistency checks against the Target information.
|
||||
if dl.endian != self.endian {
|
||||
return Err(TargetDataLayoutErrors::InconsistentTargetArchitecture {
|
||||
return Err(TargetDataLayoutError::InconsistentTargetArchitecture {
|
||||
dl: dl.endian.as_str(),
|
||||
target: self.endian.as_str(),
|
||||
});
|
||||
@@ -2183,7 +2183,7 @@ pub fn parse_data_layout(&self) -> Result<TargetDataLayout, TargetDataLayoutErro
|
||||
let target_pointer_width: u64 = self.pointer_width.into();
|
||||
let dl_pointer_size: u64 = dl.pointer_size().bits();
|
||||
if dl_pointer_size != target_pointer_width {
|
||||
return Err(TargetDataLayoutErrors::InconsistentTargetPointerWidth {
|
||||
return Err(TargetDataLayoutError::InconsistentTargetPointerWidth {
|
||||
pointer_size: dl_pointer_size,
|
||||
target: self.pointer_width,
|
||||
});
|
||||
@@ -2192,7 +2192,7 @@ pub fn parse_data_layout(&self) -> Result<TargetDataLayout, TargetDataLayoutErro
|
||||
dl.c_enum_min_size = Integer::from_size(Size::from_bits(
|
||||
self.c_enum_min_bits.unwrap_or(self.c_int_width as _),
|
||||
))
|
||||
.map_err(|err| TargetDataLayoutErrors::InvalidBitsSize { err })?;
|
||||
.map_err(|err| TargetDataLayoutError::InvalidBitsSize { err })?;
|
||||
|
||||
Ok(dl)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user