Rollup merge of #101041 - LuisCardosoOliveira:translation-rename-attr-warning-pt2, r=davidtwco
translations(rustc_session): migrates rustc_session to use SessionDiagnostic - Pt. 2
# Description
This is the second part of the `rustc_session` [migration](https://github.com/rust-lang/rust/issues/100717#issuecomment-1220279883).
**Please only review this [commit](5018581957
) that belongs to the part 2. The other ones are from the PR [#100753](https://github.com/rust-lang/rust/pull/100753) that is not yet merged.**
In this PR, we migrate the files `session.rs` and `config.rs`.
Please not that we have to `allow` the lints rules in some functions from `session.rs` because they are (at least I believe) part of the diagnostic machinery.
This commit is contained in:
commit
1561922a12
@ -14,3 +14,45 @@ session_feature_diagnostic_for_issue =
|
||||
|
||||
session_feature_diagnostic_help =
|
||||
add `#![feature({$feature})]` to the crate attributes to enable
|
||||
|
||||
session_not_circumvent_feature = `-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature gates, except when testing error paths in the CTFE engine
|
||||
|
||||
session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist.
|
||||
|
||||
session_linker_plugin_lto_windows_not_supported = linker plugin based LTO is not supported together with `-C prefer-dynamic` when targeting Windows-like targets
|
||||
|
||||
session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist.
|
||||
|
||||
session_target_requires_unwind_tables = target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no`
|
||||
|
||||
session_sanitizer_not_supported = {$us} sanitizer is not supported for this target
|
||||
|
||||
session_sanitizers_not_supported = {$us} sanitizers are not supported for this target
|
||||
|
||||
session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible with `-Zsanitizer={$second}`
|
||||
|
||||
session_cannot_enable_crt_static_linux = sanitizer is incompatible with statically linked libc, disable it using `-C target-feature=-crt-static`
|
||||
|
||||
session_sanitizer_cfi_enabled = `-Zsanitizer=cfi` requires `-Clto`
|
||||
|
||||
session_unstable_virtual_function_elimination = `-Zvirtual-function-elimination` requires `-Clto`
|
||||
|
||||
session_unsupported_dwarf_version = requested DWARF version {$dwarf_version} is greater than 5
|
||||
|
||||
session_target_invalid_address_space = invalid address space `{$addr_space}` for `{$cause}` in "data-layout": {$err}
|
||||
|
||||
session_target_invalid_bits = invalid {$kind} `{$bit}` for `{$cause}` in "data-layout": {$err}
|
||||
|
||||
session_target_missing_alignment = missing alignment for `{$cause}` in "data-layout"
|
||||
|
||||
session_target_invalid_alignment = invalid alignment for `{$cause}` in "data-layout": {$err}
|
||||
|
||||
session_target_inconsistent_architecture = inconsistent target specification: "data-layout" claims architecture is {$dl}-endian, while "target-endian" is `{$target}`
|
||||
|
||||
session_target_inconsistent_pointer_width = inconsistent target specification: "data-layout" claims pointers are {$pointer_size}-bit, while "target-pointer-width" is `{$target}`
|
||||
|
||||
session_target_invalid_bits_size = {$err}
|
||||
|
||||
session_target_stack_protector_not_supported = `-Z stack-protector={$stack_protector}` is not supported for target {$target_triple} and will be ignored
|
||||
|
||||
session_split_debuginfo_unstable_platform = `-Csplit-debuginfo={$debuginfo}` is unstable on this platform
|
||||
|
@ -10,10 +10,11 @@ use rustc_lint_defs::{Applicability, LintExpectationId};
|
||||
use rustc_span::edition::LATEST_STABLE_EDITION;
|
||||
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
|
||||
use rustc_span::{edition::Edition, Span, DUMMY_SP};
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::num::ParseIntError;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// Error type for `Diagnostic`'s `suggestions` field, indicating that
|
||||
@ -91,6 +92,10 @@ into_diagnostic_arg_using_display!(
|
||||
Edition,
|
||||
Ident,
|
||||
MacroRulesNormalizedIdent,
|
||||
ParseIntError,
|
||||
StackProtector,
|
||||
&TargetTriple,
|
||||
SplitDebuginfo
|
||||
);
|
||||
|
||||
impl IntoDiagnosticArg for bool {
|
||||
|
@ -1252,7 +1252,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
output_filenames: OutputFilenames,
|
||||
) -> GlobalCtxt<'tcx> {
|
||||
let data_layout = TargetDataLayout::parse(&s.target).unwrap_or_else(|err| {
|
||||
s.fatal(&err);
|
||||
s.emit_fatal(err);
|
||||
});
|
||||
let interners = CtxtInterners::new(arena);
|
||||
let common_types = CommonTypes::new(
|
||||
|
@ -898,7 +898,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
|
||||
let max_atomic_width = sess.target.max_atomic_width();
|
||||
let atomic_cas = sess.target.atomic_cas;
|
||||
let layout = TargetDataLayout::parse(&sess.target).unwrap_or_else(|err| {
|
||||
sess.fatal(&err);
|
||||
sess.emit_fatal(err);
|
||||
});
|
||||
|
||||
let mut ret = CrateConfig::default();
|
||||
|
@ -1,10 +1,12 @@
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use crate as rustc_session;
|
||||
use crate::cgu_reuse_tracker::CguReuse;
|
||||
use rustc_errors::MultiSpan;
|
||||
use crate::{self as rustc_session, SessionDiagnostic};
|
||||
use rustc_errors::{fluent, DiagnosticBuilder, Handler, MultiSpan};
|
||||
use rustc_macros::SessionDiagnostic;
|
||||
use rustc_span::{Span, Symbol};
|
||||
use rustc_target::abi::TargetDataLayoutErrors;
|
||||
use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple};
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(session::incorrect_cgu_reuse_type)]
|
||||
@ -43,3 +45,128 @@ pub struct FeatureDiagnosticForIssue {
|
||||
pub struct FeatureDiagnosticHelp {
|
||||
pub feature: Symbol,
|
||||
}
|
||||
|
||||
impl SessionDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
|
||||
fn into_diagnostic(self, sess: &Handler) -> DiagnosticBuilder<'_, !> {
|
||||
let mut diag;
|
||||
match self {
|
||||
TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => {
|
||||
diag = sess.struct_fatal(fluent::session::target_invalid_address_space);
|
||||
diag.set_arg("addr_space", addr_space);
|
||||
diag.set_arg("cause", cause);
|
||||
diag.set_arg("err", err);
|
||||
diag
|
||||
}
|
||||
TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => {
|
||||
diag = sess.struct_fatal(fluent::session::target_invalid_bits);
|
||||
diag.set_arg("kind", kind);
|
||||
diag.set_arg("bit", bit);
|
||||
diag.set_arg("cause", cause);
|
||||
diag.set_arg("err", err);
|
||||
diag
|
||||
}
|
||||
TargetDataLayoutErrors::MissingAlignment { cause } => {
|
||||
diag = sess.struct_fatal(fluent::session::target_missing_alignment);
|
||||
diag.set_arg("cause", cause);
|
||||
diag
|
||||
}
|
||||
TargetDataLayoutErrors::InvalidAlignment { cause, err } => {
|
||||
diag = sess.struct_fatal(fluent::session::target_invalid_alignment);
|
||||
diag.set_arg("cause", cause);
|
||||
diag.set_arg("err", err);
|
||||
diag
|
||||
}
|
||||
TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
|
||||
diag = sess.struct_fatal(fluent::session::target_inconsistent_architecture);
|
||||
diag.set_arg("dl", dl);
|
||||
diag.set_arg("target", target);
|
||||
diag
|
||||
}
|
||||
TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => {
|
||||
diag = sess.struct_fatal(fluent::session::target_inconsistent_pointer_width);
|
||||
diag.set_arg("pointer_size", pointer_size);
|
||||
diag.set_arg("target", target);
|
||||
diag
|
||||
}
|
||||
TargetDataLayoutErrors::InvalidBitsSize { err } => {
|
||||
diag = sess.struct_fatal(fluent::session::target_invalid_bits_size);
|
||||
diag.set_arg("err", err);
|
||||
diag
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(session::not_circumvent_feature)]
|
||||
pub struct NotCircumventFeature;
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(session::linker_plugin_lto_windows_not_supported)]
|
||||
pub struct LinkerPluginToWindowsNotSupported;
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(session::profile_use_file_does_not_exist)]
|
||||
pub struct ProfileUseFileDoesNotExist<'a> {
|
||||
pub path: &'a std::path::Path,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(session::profile_sample_use_file_does_not_exist)]
|
||||
pub struct ProfileSampleUseFileDoesNotExist<'a> {
|
||||
pub path: &'a std::path::Path,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(session::target_requires_unwind_tables)]
|
||||
pub struct TargetRequiresUnwindTables;
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(session::sanitizer_not_supported)]
|
||||
pub struct SanitizerNotSupported {
|
||||
pub us: String,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(session::sanitizers_not_supported)]
|
||||
pub struct SanitizersNotSupported {
|
||||
pub us: String,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(session::cannot_mix_and_match_sanitizers)]
|
||||
pub struct CannotMixAndMatchSanitizers {
|
||||
pub first: String,
|
||||
pub second: String,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(session::cannot_enable_crt_static_linux)]
|
||||
pub struct CannotEnableCrtStaticLinux;
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(session::sanitizer_cfi_enabled)]
|
||||
pub struct SanitizerCfiEnabled;
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(session::unstable_virtual_function_elimination)]
|
||||
pub struct UnstableVirtualFunctionElimination;
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(session::unsupported_dwarf_version)]
|
||||
pub struct UnsupportedDwarfVersion {
|
||||
pub dwarf_version: u32,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(session::target_stack_protector_not_supported)]
|
||||
pub struct StackProtectorNotSupportedForTarget<'a> {
|
||||
pub stack_protector: StackProtector,
|
||||
pub target_triple: &'a TargetTriple,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(session::split_debuginfo_unstable_platform)]
|
||||
pub struct SplitDebugInfoUnstablePlatform {
|
||||
pub debuginfo: SplitDebuginfo,
|
||||
}
|
||||
|
@ -2,6 +2,13 @@ use crate::cgu_reuse_tracker::CguReuseTracker;
|
||||
use crate::code_stats::CodeStats;
|
||||
pub use crate::code_stats::{DataTypeKind, FieldInfo, SizeKind, VariantInfo};
|
||||
use crate::config::{self, CrateType, InstrumentCoverage, OptLevel, OutputType, SwitchWithOptPath};
|
||||
use crate::errors::{
|
||||
CannotEnableCrtStaticLinux, CannotMixAndMatchSanitizers, LinkerPluginToWindowsNotSupported,
|
||||
NotCircumventFeature, ProfileSampleUseFileDoesNotExist, ProfileUseFileDoesNotExist,
|
||||
SanitizerCfiEnabled, SanitizerNotSupported, SanitizersNotSupported,
|
||||
SplitDebugInfoUnstablePlatform, StackProtectorNotSupportedForTarget,
|
||||
TargetRequiresUnwindTables, UnstableVirtualFunctionElimination, UnsupportedDwarfVersion,
|
||||
};
|
||||
use crate::parse::{add_feature_diagnostics, ParseSess};
|
||||
use crate::search_paths::{PathKind, SearchPath};
|
||||
use crate::{filesearch, lint};
|
||||
@ -235,6 +242,9 @@ impl Session {
|
||||
if !unleashed_features.is_empty() {
|
||||
let mut must_err = false;
|
||||
// Create a diagnostic pointing at where things got unleashed.
|
||||
// FIXME(#100717): needs eager translation/lists
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
let mut diag = self.struct_warn("skipping const checks");
|
||||
for &(span, feature_gate) in unleashed_features.iter() {
|
||||
// FIXME: `span_label` doesn't do anything, so we use "help" as a hack.
|
||||
@ -250,10 +260,7 @@ impl Session {
|
||||
// If we should err, make sure we did.
|
||||
if must_err && self.has_errors().is_none() {
|
||||
// We have skipped a feature gate, and not run into other errors... reject.
|
||||
self.err(
|
||||
"`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature \
|
||||
gates, except when testing error paths in the CTFE engine",
|
||||
);
|
||||
self.emit_err(NotCircumventFeature);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -534,9 +541,13 @@ impl Session {
|
||||
Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
|
||||
}
|
||||
}
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) {
|
||||
self.diagnostic().span_warn(sp, msg)
|
||||
}
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
pub fn span_warn_with_code<S: Into<MultiSpan>>(
|
||||
&self,
|
||||
sp: S,
|
||||
@ -585,6 +596,8 @@ impl Session {
|
||||
) {
|
||||
self.diagnostic().span_note_without_error(sp, msg)
|
||||
}
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
pub fn struct_note_without_error(
|
||||
&self,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
@ -1469,40 +1482,28 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
|
||||
&& sess.opts.cg.prefer_dynamic
|
||||
&& sess.target.is_like_windows
|
||||
{
|
||||
sess.err(
|
||||
"Linker plugin based LTO is not supported together with \
|
||||
`-C prefer-dynamic` when targeting Windows-like targets",
|
||||
);
|
||||
sess.emit_err(LinkerPluginToWindowsNotSupported);
|
||||
}
|
||||
|
||||
// Make sure that any given profiling data actually exists so LLVM can't
|
||||
// decide to silently skip PGO.
|
||||
if let Some(ref path) = sess.opts.cg.profile_use {
|
||||
if !path.exists() {
|
||||
sess.err(&format!(
|
||||
"File `{}` passed to `-C profile-use` does not exist.",
|
||||
path.display()
|
||||
));
|
||||
sess.emit_err(ProfileUseFileDoesNotExist { path });
|
||||
}
|
||||
}
|
||||
|
||||
// Do the same for sample profile data.
|
||||
if let Some(ref path) = sess.opts.unstable_opts.profile_sample_use {
|
||||
if !path.exists() {
|
||||
sess.err(&format!(
|
||||
"File `{}` passed to `-C profile-sample-use` does not exist.",
|
||||
path.display()
|
||||
));
|
||||
sess.emit_err(ProfileSampleUseFileDoesNotExist { path });
|
||||
}
|
||||
}
|
||||
|
||||
// Unwind tables cannot be disabled if the target requires them.
|
||||
if let Some(include_uwtables) = sess.opts.cg.force_unwind_tables {
|
||||
if sess.target.requires_uwtable && !include_uwtables {
|
||||
sess.err(
|
||||
"target requires unwind tables, they cannot be disabled with \
|
||||
`-C force-unwind-tables=no`.",
|
||||
);
|
||||
sess.emit_err(TargetRequiresUnwindTables);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1512,64 +1513,55 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
|
||||
match unsupported_sanitizers.into_iter().count() {
|
||||
0 => {}
|
||||
1 => {
|
||||
sess.err(&format!(
|
||||
"{} sanitizer is not supported for this target",
|
||||
unsupported_sanitizers
|
||||
));
|
||||
sess.emit_err(SanitizerNotSupported { us: unsupported_sanitizers.to_string() });
|
||||
}
|
||||
_ => {
|
||||
sess.err(&format!(
|
||||
"{} sanitizers are not supported for this target",
|
||||
unsupported_sanitizers
|
||||
));
|
||||
sess.emit_err(SanitizersNotSupported { us: unsupported_sanitizers.to_string() });
|
||||
}
|
||||
}
|
||||
// Cannot mix and match sanitizers.
|
||||
let mut sanitizer_iter = sess.opts.unstable_opts.sanitizer.into_iter();
|
||||
if let (Some(first), Some(second)) = (sanitizer_iter.next(), sanitizer_iter.next()) {
|
||||
sess.err(&format!("`-Zsanitizer={first}` is incompatible with `-Zsanitizer={second}`"));
|
||||
sess.emit_err(CannotMixAndMatchSanitizers {
|
||||
first: first.to_string(),
|
||||
second: second.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
// Cannot enable crt-static with sanitizers on Linux
|
||||
if sess.crt_static(None) && !sess.opts.unstable_opts.sanitizer.is_empty() {
|
||||
sess.err(
|
||||
"sanitizer is incompatible with statically linked libc, \
|
||||
disable it using `-C target-feature=-crt-static`",
|
||||
);
|
||||
sess.emit_err(CannotEnableCrtStaticLinux);
|
||||
}
|
||||
|
||||
// LLVM CFI and VFE both require LTO.
|
||||
if sess.lto() != config::Lto::Fat {
|
||||
if sess.is_sanitizer_cfi_enabled() {
|
||||
sess.err("`-Zsanitizer=cfi` requires `-Clto`");
|
||||
sess.emit_err(SanitizerCfiEnabled);
|
||||
}
|
||||
if sess.opts.unstable_opts.virtual_function_elimination {
|
||||
sess.err("`-Zvirtual-function-elimination` requires `-Clto`");
|
||||
sess.emit_err(UnstableVirtualFunctionElimination);
|
||||
}
|
||||
}
|
||||
|
||||
if sess.opts.unstable_opts.stack_protector != StackProtector::None {
|
||||
if !sess.target.options.supports_stack_protector {
|
||||
sess.warn(&format!(
|
||||
"`-Z stack-protector={}` is not supported for target {} and will be ignored",
|
||||
sess.opts.unstable_opts.stack_protector, sess.opts.target_triple
|
||||
))
|
||||
sess.emit_warning(StackProtectorNotSupportedForTarget {
|
||||
stack_protector: sess.opts.unstable_opts.stack_protector,
|
||||
target_triple: &sess.opts.target_triple,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(dwarf_version) = sess.opts.unstable_opts.dwarf_version {
|
||||
if dwarf_version > 5 {
|
||||
sess.err(&format!("requested DWARF version {} is greater than 5", dwarf_version));
|
||||
sess.emit_err(UnsupportedDwarfVersion { dwarf_version });
|
||||
}
|
||||
}
|
||||
|
||||
if !sess.target.options.supported_split_debuginfo.contains(&sess.split_debuginfo())
|
||||
&& !sess.opts.unstable_opts.unstable_options
|
||||
{
|
||||
sess.err(&format!(
|
||||
"`-Csplit-debuginfo={}` is unstable on this platform",
|
||||
sess.split_debuginfo()
|
||||
));
|
||||
sess.emit_err(SplitDebugInfoUnstablePlatform { debuginfo: sess.split_debuginfo() });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1614,14 +1606,20 @@ fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler
|
||||
rustc_errors::Handler::with_emitter(true, None, emitter)
|
||||
}
|
||||
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) -> ErrorGuaranteed {
|
||||
early_error_handler(output).struct_err(msg).emit()
|
||||
}
|
||||
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
|
||||
early_error_handler(output).struct_fatal(msg).emit()
|
||||
}
|
||||
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
|
||||
early_error_handler(output).struct_warn(msg).emit()
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use crate::spec::Target;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::fmt;
|
||||
use std::iter::Step;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::num::{NonZeroUsize, ParseIntError};
|
||||
use std::ops::{Add, AddAssign, Deref, Mul, RangeInclusive, Sub};
|
||||
use std::str::FromStr;
|
||||
|
||||
@ -69,34 +69,46 @@ impl Default for TargetDataLayout {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum TargetDataLayoutErrors<'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 },
|
||||
InvalidAlignment { cause: &'a str, err: String },
|
||||
InconsistentTargetArchitecture { dl: &'a str, target: &'a str },
|
||||
InconsistentTargetPointerWidth { pointer_size: u64, target: u32 },
|
||||
InvalidBitsSize { err: String },
|
||||
}
|
||||
|
||||
impl TargetDataLayout {
|
||||
pub fn parse(target: &Target) -> Result<TargetDataLayout, String> {
|
||||
pub fn parse<'a>(target: &'a Target) -> Result<TargetDataLayout, TargetDataLayoutErrors<'a>> {
|
||||
// Parse an address space index from a string.
|
||||
let parse_address_space = |s: &str, cause: &str| {
|
||||
let parse_address_space = |s: &'a str, cause: &'a str| {
|
||||
s.parse::<u32>().map(AddressSpace).map_err(|err| {
|
||||
format!("invalid address space `{}` for `{}` in \"data-layout\": {}", s, cause, err)
|
||||
TargetDataLayoutErrors::InvalidAddressSpace { addr_space: s, cause, err }
|
||||
})
|
||||
};
|
||||
|
||||
// Parse a bit count from a string.
|
||||
let parse_bits = |s: &str, kind: &str, cause: &str| {
|
||||
s.parse::<u64>().map_err(|err| {
|
||||
format!("invalid {} `{}` for `{}` in \"data-layout\": {}", kind, s, cause, err)
|
||||
let parse_bits = |s: &'a str, kind: &'a str, cause: &'a str| {
|
||||
s.parse::<u64>().map_err(|err| TargetDataLayoutErrors::InvalidBits {
|
||||
kind,
|
||||
bit: s,
|
||||
cause,
|
||||
err,
|
||||
})
|
||||
};
|
||||
|
||||
// Parse a size string.
|
||||
let size = |s: &str, cause: &str| parse_bits(s, "size", cause).map(Size::from_bits);
|
||||
let size = |s: &'a str, cause: &'a str| parse_bits(s, "size", cause).map(Size::from_bits);
|
||||
|
||||
// Parse an alignment string.
|
||||
let align = |s: &[&str], cause: &str| {
|
||||
let align = |s: &[&'a str], cause: &'a str| {
|
||||
if s.is_empty() {
|
||||
return Err(format!("missing alignment for `{}` in \"data-layout\"", cause));
|
||||
return Err(TargetDataLayoutErrors::MissingAlignment { cause });
|
||||
}
|
||||
let align_from_bits = |bits| {
|
||||
Align::from_bits(bits).map_err(|err| {
|
||||
format!("invalid alignment for `{}` in \"data-layout\": {}", cause, err)
|
||||
})
|
||||
Align::from_bits(bits)
|
||||
.map_err(|err| TargetDataLayoutErrors::InvalidAlignment { cause, err })
|
||||
};
|
||||
let abi = parse_bits(s[0], "alignment", cause)?;
|
||||
let pref = s.get(1).map_or(Ok(abi), |pref| parse_bits(pref, "alignment", cause))?;
|
||||
@ -158,25 +170,24 @@ impl TargetDataLayout {
|
||||
|
||||
// Perform consistency checks against the Target information.
|
||||
if dl.endian != target.endian {
|
||||
return Err(format!(
|
||||
"inconsistent target specification: \"data-layout\" claims \
|
||||
architecture is {}-endian, while \"target-endian\" is `{}`",
|
||||
dl.endian.as_str(),
|
||||
target.endian.as_str(),
|
||||
));
|
||||
return Err(TargetDataLayoutErrors::InconsistentTargetArchitecture {
|
||||
dl: dl.endian.as_str(),
|
||||
target: target.endian.as_str(),
|
||||
});
|
||||
}
|
||||
|
||||
let target_pointer_width: u64 = target.pointer_width.into();
|
||||
if dl.pointer_size.bits() != target_pointer_width {
|
||||
return Err(format!(
|
||||
"inconsistent target specification: \"data-layout\" claims \
|
||||
pointers are {}-bit, while \"target-pointer-width\" is `{}`",
|
||||
dl.pointer_size.bits(),
|
||||
target.pointer_width
|
||||
));
|
||||
return Err(TargetDataLayoutErrors::InconsistentTargetPointerWidth {
|
||||
pointer_size: dl.pointer_size.bits(),
|
||||
target: target.pointer_width,
|
||||
});
|
||||
}
|
||||
|
||||
dl.c_enum_min_size = Integer::from_size(Size::from_bits(target.c_enum_min_bits))?;
|
||||
dl.c_enum_min_size = match Integer::from_size(Size::from_bits(target.c_enum_min_bits)) {
|
||||
Ok(bits) => bits,
|
||||
Err(err) => return Err(TargetDataLayoutErrors::InvalidBitsSize { err }),
|
||||
};
|
||||
|
||||
Ok(dl)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user