Auto merge of #105125 - matthiaskrgr:rollup-fr0snmj, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #105078 (Fix `expr_to_spanned_string` ICE) - #105087 (Extract llvm datalayout parsing out of spec module) - #105088 (rustdoc: remove redundant CSS `div.desc { display: block }`) - #105106 (Fix ICE from #105101) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
c090c6880c
@ -211,6 +211,102 @@ pub enum TargetDataLayoutErrors<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TargetDataLayout {
|
impl TargetDataLayout {
|
||||||
|
/// Parse data layout from an [llvm data layout string](https://llvm.org/docs/LangRef.html#data-layout)
|
||||||
|
///
|
||||||
|
/// This function doesn't fill `c_enum_min_size` and it will always be `I32` since it can not be
|
||||||
|
/// determined from llvm string.
|
||||||
|
pub fn parse_from_llvm_datalayout_string<'a>(
|
||||||
|
input: &'a str,
|
||||||
|
) -> Result<TargetDataLayout, TargetDataLayoutErrors<'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 }
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
kind,
|
||||||
|
bit: s,
|
||||||
|
cause,
|
||||||
|
err,
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parse a size string.
|
||||||
|
let size = |s: &'a str, cause: &'a str| parse_bits(s, "size", cause).map(Size::from_bits);
|
||||||
|
|
||||||
|
// Parse an alignment string.
|
||||||
|
let align = |s: &[&'a str], cause: &'a str| {
|
||||||
|
if s.is_empty() {
|
||||||
|
return Err(TargetDataLayoutErrors::MissingAlignment { cause });
|
||||||
|
}
|
||||||
|
let align_from_bits = |bits| {
|
||||||
|
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))?;
|
||||||
|
Ok(AbiAndPrefAlign { abi: align_from_bits(abi)?, pref: align_from_bits(pref)? })
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut dl = TargetDataLayout::default();
|
||||||
|
let mut i128_align_src = 64;
|
||||||
|
for spec in input.split('-') {
|
||||||
|
let spec_parts = spec.split(':').collect::<Vec<_>>();
|
||||||
|
|
||||||
|
match &*spec_parts {
|
||||||
|
["e"] => dl.endian = Endian::Little,
|
||||||
|
["E"] => dl.endian = Endian::Big,
|
||||||
|
[p] if p.starts_with('P') => {
|
||||||
|
dl.instruction_address_space = parse_address_space(&p[1..], "P")?
|
||||||
|
}
|
||||||
|
["a", ref a @ ..] => dl.aggregate_align = align(a, "a")?,
|
||||||
|
["f32", ref a @ ..] => dl.f32_align = align(a, "f32")?,
|
||||||
|
["f64", ref a @ ..] => dl.f64_align = align(a, "f64")?,
|
||||||
|
[p @ "p", s, ref a @ ..] | [p @ "p0", s, ref a @ ..] => {
|
||||||
|
dl.pointer_size = size(s, p)?;
|
||||||
|
dl.pointer_align = align(a, p)?;
|
||||||
|
}
|
||||||
|
[s, ref a @ ..] if s.starts_with('i') => {
|
||||||
|
let Ok(bits) = s[1..].parse::<u64>() else {
|
||||||
|
size(&s[1..], "i")?; // For the user error.
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let a = align(a, s)?;
|
||||||
|
match bits {
|
||||||
|
1 => dl.i1_align = a,
|
||||||
|
8 => dl.i8_align = a,
|
||||||
|
16 => dl.i16_align = a,
|
||||||
|
32 => dl.i32_align = a,
|
||||||
|
64 => dl.i64_align = a,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
if bits >= i128_align_src && bits <= 128 {
|
||||||
|
// Default alignment for i128 is decided by taking the alignment of
|
||||||
|
// largest-sized i{64..=128}.
|
||||||
|
i128_align_src = bits;
|
||||||
|
dl.i128_align = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[s, ref a @ ..] if s.starts_with('v') => {
|
||||||
|
let v_size = size(&s[1..], "v")?;
|
||||||
|
let a = align(a, s)?;
|
||||||
|
if let Some(v) = dl.vector_align.iter_mut().find(|v| v.0 == v_size) {
|
||||||
|
v.1 = a;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// No existing entry, add a new one.
|
||||||
|
dl.vector_align.push((v_size, a));
|
||||||
|
}
|
||||||
|
_ => {} // Ignore everything else.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(dl)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns exclusive upper bound on object size.
|
/// Returns exclusive upper bound on object size.
|
||||||
///
|
///
|
||||||
/// The theoretical maximum object size is defined as the maximum positive `isize` value.
|
/// The theoretical maximum object size is defined as the maximum positive `isize` value.
|
||||||
|
@ -145,7 +145,7 @@ fn extract_default_variant<'a>(
|
|||||||
let suggestion = default_variants
|
let suggestion = default_variants
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|v| {
|
.filter_map(|v| {
|
||||||
if v.ident == variant.ident {
|
if v.span == variant.span {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some((cx.sess.find_by_name(&v.attrs, kw::Default)?.span, String::new()))
|
Some((cx.sess.find_by_name(&v.attrs, kw::Default)?.span, String::new()))
|
||||||
|
@ -16,6 +16,7 @@ use rustc_errors::{
|
|||||||
use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
|
use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
|
||||||
use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics};
|
use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics};
|
||||||
use rustc_parse::{self, parser, MACRO_ARGUMENTS};
|
use rustc_parse::{self, parser, MACRO_ARGUMENTS};
|
||||||
|
use rustc_session::errors::report_lit_error;
|
||||||
use rustc_session::{parse::ParseSess, Limit, Session};
|
use rustc_session::{parse::ParseSess, Limit, Session};
|
||||||
use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
|
use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
@ -1245,7 +1246,10 @@ pub fn expr_to_spanned_string<'a>(
|
|||||||
Some((err, true))
|
Some((err, true))
|
||||||
}
|
}
|
||||||
Ok(ast::LitKind::Err) => None,
|
Ok(ast::LitKind::Err) => None,
|
||||||
Err(_) => None,
|
Err(err) => {
|
||||||
|
report_lit_error(&cx.sess.parse_sess, err, token_lit, expr.span);
|
||||||
|
None
|
||||||
|
}
|
||||||
_ => Some((cx.struct_span_err(expr.span, err_msg), false)),
|
_ => Some((cx.struct_span_err(expr.span, err_msg), false)),
|
||||||
},
|
},
|
||||||
ast::ExprKind::Err => None,
|
ast::ExprKind::Err => None,
|
||||||
|
@ -197,12 +197,12 @@ pub enum UnleashedFeatureHelp {
|
|||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(session_invalid_literal_suffix)]
|
#[diag(session_invalid_literal_suffix)]
|
||||||
pub(crate) struct InvalidLiteralSuffix {
|
pub(crate) struct InvalidLiteralSuffix<'a> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
// FIXME(#100717)
|
// FIXME(#100717)
|
||||||
pub kind: String,
|
pub kind: &'a str,
|
||||||
pub suffix: Symbol,
|
pub suffix: Symbol,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,11 +311,7 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
|
|||||||
LitError::LexerError => {}
|
LitError::LexerError => {}
|
||||||
LitError::InvalidSuffix => {
|
LitError::InvalidSuffix => {
|
||||||
if let Some(suffix) = suffix {
|
if let Some(suffix) = suffix {
|
||||||
sess.emit_err(InvalidLiteralSuffix {
|
sess.emit_err(InvalidLiteralSuffix { span, kind: kind.descr(), suffix });
|
||||||
span,
|
|
||||||
kind: format!("{}", kind.descr()),
|
|
||||||
suffix,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LitError::InvalidIntSuffix => {
|
LitError::InvalidIntSuffix => {
|
||||||
|
@ -35,10 +35,7 @@
|
|||||||
//! to the list specified by the target, rather than replace.
|
//! to the list specified by the target, rather than replace.
|
||||||
|
|
||||||
use crate::abi::call::Conv;
|
use crate::abi::call::Conv;
|
||||||
use crate::abi::{
|
use crate::abi::{Endian, Integer, Size, TargetDataLayout, TargetDataLayoutErrors};
|
||||||
AbiAndPrefAlign, AddressSpace, Align, Endian, Integer, Size, TargetDataLayout,
|
|
||||||
TargetDataLayoutErrors,
|
|
||||||
};
|
|
||||||
use crate::json::{Json, ToJson};
|
use crate::json::{Json, ToJson};
|
||||||
use crate::spec::abi::{lookup as lookup_abi, Abi};
|
use crate::spec::abi::{lookup as lookup_abi, Abi};
|
||||||
use crate::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
|
use crate::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
|
||||||
@ -1322,92 +1319,7 @@ pub struct Target {
|
|||||||
|
|
||||||
impl Target {
|
impl Target {
|
||||||
pub fn parse_data_layout<'a>(&'a self) -> Result<TargetDataLayout, TargetDataLayoutErrors<'a>> {
|
pub fn parse_data_layout<'a>(&'a self) -> Result<TargetDataLayout, TargetDataLayoutErrors<'a>> {
|
||||||
// Parse an address space index from a string.
|
let mut dl = TargetDataLayout::parse_from_llvm_datalayout_string(&self.data_layout)?;
|
||||||
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 }
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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 {
|
|
||||||
kind,
|
|
||||||
bit: s,
|
|
||||||
cause,
|
|
||||||
err,
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// Parse a size string.
|
|
||||||
let size = |s: &'a str, cause: &'a str| parse_bits(s, "size", cause).map(Size::from_bits);
|
|
||||||
|
|
||||||
// Parse an alignment string.
|
|
||||||
let align = |s: &[&'a str], cause: &'a str| {
|
|
||||||
if s.is_empty() {
|
|
||||||
return Err(TargetDataLayoutErrors::MissingAlignment { cause });
|
|
||||||
}
|
|
||||||
let align_from_bits = |bits| {
|
|
||||||
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))?;
|
|
||||||
Ok(AbiAndPrefAlign { abi: align_from_bits(abi)?, pref: align_from_bits(pref)? })
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut dl = TargetDataLayout::default();
|
|
||||||
let mut i128_align_src = 64;
|
|
||||||
for spec in self.data_layout.split('-') {
|
|
||||||
let spec_parts = spec.split(':').collect::<Vec<_>>();
|
|
||||||
|
|
||||||
match &*spec_parts {
|
|
||||||
["e"] => dl.endian = Endian::Little,
|
|
||||||
["E"] => dl.endian = Endian::Big,
|
|
||||||
[p] if p.starts_with('P') => {
|
|
||||||
dl.instruction_address_space = parse_address_space(&p[1..], "P")?
|
|
||||||
}
|
|
||||||
["a", ref a @ ..] => dl.aggregate_align = align(a, "a")?,
|
|
||||||
["f32", ref a @ ..] => dl.f32_align = align(a, "f32")?,
|
|
||||||
["f64", ref a @ ..] => dl.f64_align = align(a, "f64")?,
|
|
||||||
[p @ "p", s, ref a @ ..] | [p @ "p0", s, ref a @ ..] => {
|
|
||||||
dl.pointer_size = size(s, p)?;
|
|
||||||
dl.pointer_align = align(a, p)?;
|
|
||||||
}
|
|
||||||
[s, ref a @ ..] if s.starts_with('i') => {
|
|
||||||
let Ok(bits) = s[1..].parse::<u64>() else {
|
|
||||||
size(&s[1..], "i")?; // For the user error.
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
let a = align(a, s)?;
|
|
||||||
match bits {
|
|
||||||
1 => dl.i1_align = a,
|
|
||||||
8 => dl.i8_align = a,
|
|
||||||
16 => dl.i16_align = a,
|
|
||||||
32 => dl.i32_align = a,
|
|
||||||
64 => dl.i64_align = a,
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
if bits >= i128_align_src && bits <= 128 {
|
|
||||||
// Default alignment for i128 is decided by taking the alignment of
|
|
||||||
// largest-sized i{64..=128}.
|
|
||||||
i128_align_src = bits;
|
|
||||||
dl.i128_align = a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[s, ref a @ ..] if s.starts_with('v') => {
|
|
||||||
let v_size = size(&s[1..], "v")?;
|
|
||||||
let a = align(a, s)?;
|
|
||||||
if let Some(v) = dl.vector_align.iter_mut().find(|v| v.0 == v_size) {
|
|
||||||
v.1 = a;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// No existing entry, add a new one.
|
|
||||||
dl.vector_align.push((v_size, a));
|
|
||||||
}
|
|
||||||
_ => {} // Ignore everything else.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform consistency checks against the Target information.
|
// Perform consistency checks against the Target information.
|
||||||
if dl.endian != self.endian {
|
if dl.endian != self.endian {
|
||||||
|
@ -894,7 +894,6 @@ so that we can apply CSS-filters to change the arrow color in themes */
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-results a:hover,
|
.search-results a:hover,
|
||||||
|
9
src/test/ui/deriving/issue-105101.rs
Normal file
9
src/test/ui/deriving/issue-105101.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// compile-flags: --crate-type=lib
|
||||||
|
|
||||||
|
#[derive(Default)] //~ ERROR multiple declared defaults
|
||||||
|
enum E {
|
||||||
|
#[default]
|
||||||
|
A,
|
||||||
|
#[default]
|
||||||
|
A, //~ ERROR defined multiple times
|
||||||
|
}
|
29
src/test/ui/deriving/issue-105101.stderr
Normal file
29
src/test/ui/deriving/issue-105101.stderr
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
error: multiple declared defaults
|
||||||
|
--> $DIR/issue-105101.rs:3:10
|
||||||
|
|
|
||||||
|
LL | #[derive(Default)]
|
||||||
|
| ^^^^^^^
|
||||||
|
...
|
||||||
|
LL | A,
|
||||||
|
| - first default
|
||||||
|
LL | #[default]
|
||||||
|
LL | A,
|
||||||
|
| - additional default
|
||||||
|
|
|
||||||
|
= note: only one variant can be default
|
||||||
|
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error[E0428]: the name `A` is defined multiple times
|
||||||
|
--> $DIR/issue-105101.rs:8:5
|
||||||
|
|
|
||||||
|
LL | A,
|
||||||
|
| - previous definition of the type `A` here
|
||||||
|
LL | #[default]
|
||||||
|
LL | A,
|
||||||
|
| ^ `A` redefined here
|
||||||
|
|
|
||||||
|
= note: `A` must be defined only once in the type namespace of this enum
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0428`.
|
3
src/test/ui/macros/issue-105011.rs
Normal file
3
src/test/ui/macros/issue-105011.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
println!(""y); //~ ERROR suffixes on string literals are invalid
|
||||||
|
}
|
8
src/test/ui/macros/issue-105011.stderr
Normal file
8
src/test/ui/macros/issue-105011.stderr
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
error: suffixes on string literals are invalid
|
||||||
|
--> $DIR/issue-105011.rs:2:14
|
||||||
|
|
|
||||||
|
LL | println!(""y);
|
||||||
|
| ^^^ invalid suffix `y`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user