From 97f0c58b37ba7e1bd32ddf1c4558884302f68194 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 30 Nov 2022 13:31:11 +0900 Subject: [PATCH 1/5] report literal errors when `token_lit` has errors --- compiler/rustc_expand/src/base.rs | 6 +++++- src/test/ui/macros/issue-105011.rs | 3 +++ src/test/ui/macros/issue-105011.stderr | 8 ++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/macros/issue-105011.rs create mode 100644 src/test/ui/macros/issue-105011.stderr diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 8955abebf1e..fc74182b872 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -16,6 +16,7 @@ use rustc_errors::{ use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT; use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics}; use rustc_parse::{self, parser, MACRO_ARGUMENTS}; +use rustc_session::errors::report_lit_error; use rustc_session::{parse::ParseSess, Limit, Session}; use rustc_span::def_id::{CrateNum, DefId, LocalDefId}; use rustc_span::edition::Edition; @@ -1245,7 +1246,10 @@ pub fn expr_to_spanned_string<'a>( Some((err, true)) } 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)), }, ast::ExprKind::Err => None, diff --git a/src/test/ui/macros/issue-105011.rs b/src/test/ui/macros/issue-105011.rs new file mode 100644 index 00000000000..da12c381464 --- /dev/null +++ b/src/test/ui/macros/issue-105011.rs @@ -0,0 +1,3 @@ +fn main() { + println!(""y); //~ ERROR suffixes on string literals are invalid +} diff --git a/src/test/ui/macros/issue-105011.stderr b/src/test/ui/macros/issue-105011.stderr new file mode 100644 index 00000000000..e898af7faa3 --- /dev/null +++ b/src/test/ui/macros/issue-105011.stderr @@ -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 + From 02eaecc767b5f8deb1f1e3ddc7c0a793b6e7ff2d Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 30 Nov 2022 13:31:35 +0900 Subject: [PATCH 2/5] avoid an unnecessary `&str` to `String` conversion --- compiler/rustc_session/src/errors.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 2f7055e3cc5..9aa8a06c6d3 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -197,12 +197,12 @@ pub enum UnleashedFeatureHelp { #[derive(Diagnostic)] #[diag(session_invalid_literal_suffix)] -pub(crate) struct InvalidLiteralSuffix { +pub(crate) struct InvalidLiteralSuffix<'a> { #[primary_span] #[label] pub span: Span, // FIXME(#100717) - pub kind: String, + pub kind: &'a str, pub suffix: Symbol, } @@ -311,11 +311,7 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span: LitError::LexerError => {} LitError::InvalidSuffix => { if let Some(suffix) = suffix { - sess.emit_err(InvalidLiteralSuffix { - span, - kind: format!("{}", kind.descr()), - suffix, - }); + sess.emit_err(InvalidLiteralSuffix { span, kind: kind.descr(), suffix }); } } LitError::InvalidIntSuffix => { From 2405e607696698e5d9cf0d2eec46bd3fbc339e5b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 30 Nov 2022 09:00:02 -0700 Subject: [PATCH 3/5] rustdoc: remove redundant CSS `div.desc { display: block }` DIV tags have block display by default. It is from when this rule used to target a SPAN tag, but became redundant in 4bd6748bb9b73c210558498070ae0b7ed8193ddf. --- src/librustdoc/html/static/css/rustdoc.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index de882e66f43..85bd73db524 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -896,7 +896,6 @@ so that we can apply CSS-filters to change the arrow color in themes */ white-space: nowrap; text-overflow: ellipsis; overflow: hidden; - display: block; } .search-results a:hover, From 56126fb149ea810db234e210893833e97a5c8e36 Mon Sep 17 00:00:00 2001 From: hkalbasi Date: Wed, 30 Nov 2022 19:13:09 +0330 Subject: [PATCH 4/5] Extract llvm datalayout parsing out of spec module --- compiler/rustc_abi/src/lib.rs | 96 +++++++++++++++++++++++++++ compiler/rustc_target/src/spec/mod.rs | 92 +------------------------ 2 files changed, 98 insertions(+), 90 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 4f4a4bf314f..85693259cd0 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -211,6 +211,102 @@ pub enum TargetDataLayoutErrors<'a> { } 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> { + // Parse an address space index from a string. + let parse_address_space = |s: &'a str, cause: &'a str| { + s.parse::().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::().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::>(); + + 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::() 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. /// /// The theoretical maximum object size is defined as the maximum positive `isize` value. diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 0f8cfd7f538..78315afa759 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -35,10 +35,7 @@ //! to the list specified by the target, rather than replace. use crate::abi::call::Conv; -use crate::abi::{ - AbiAndPrefAlign, AddressSpace, Align, Endian, Integer, Size, TargetDataLayout, - TargetDataLayoutErrors, -}; +use crate::abi::{Endian, Integer, Size, TargetDataLayout, TargetDataLayoutErrors}; use crate::json::{Json, ToJson}; use crate::spec::abi::{lookup as lookup_abi, Abi}; use crate::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault}; @@ -1322,92 +1319,7 @@ pub struct Target { impl Target { pub fn parse_data_layout<'a>(&'a self) -> Result> { - // Parse an address space index from a string. - let parse_address_space = |s: &'a str, cause: &'a str| { - s.parse::().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::().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::>(); - - 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::() 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. - } - } + let mut dl = TargetDataLayout::parse_from_llvm_datalayout_string(&self.data_layout)?; // Perform consistency checks against the Target information. if dl.endian != self.endian { From ab264ae61217df6a2b66c8f2bbff294b793a1f94 Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Wed, 30 Nov 2022 21:17:00 +0000 Subject: [PATCH 5/5] Fix ICE from #105101 --- .../src/deriving/default.rs | 2 +- src/test/ui/deriving/issue-105101.rs | 9 ++++++ src/test/ui/deriving/issue-105101.stderr | 29 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/deriving/issue-105101.rs create mode 100644 src/test/ui/deriving/issue-105101.stderr diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 93f297ad88b..bd5c6e42a19 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -146,7 +146,7 @@ fn extract_default_variant<'a>( let suggestion = default_variants .iter() .filter_map(|v| { - if v.ident == variant.ident { + if v.span == variant.span { None } else { Some((cx.sess.find_by_name(&v.attrs, kw::Default)?.span, String::new())) diff --git a/src/test/ui/deriving/issue-105101.rs b/src/test/ui/deriving/issue-105101.rs new file mode 100644 index 00000000000..1a377feb919 --- /dev/null +++ b/src/test/ui/deriving/issue-105101.rs @@ -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 +} diff --git a/src/test/ui/deriving/issue-105101.stderr b/src/test/ui/deriving/issue-105101.stderr new file mode 100644 index 00000000000..0f6f67043f3 --- /dev/null +++ b/src/test/ui/deriving/issue-105101.stderr @@ -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`.