From 7ee01b4b800233db0d494d433b318ce06ec25115 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Thu, 23 Feb 2023 18:51:31 +0000 Subject: [PATCH 1/8] Lazily compute crate name for consider_optimizing The extra query is unnecessary in the common case of not having fuel. --- compiler/rustc_middle/src/ty/context.rs | 3 +-- compiler/rustc_session/src/session.rs | 10 +++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 7e6a6e71670f3..9027422167d04 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -793,8 +793,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn consider_optimizing String>(self, msg: T) -> bool { - let cname = self.crate_name(LOCAL_CRATE); - self.sess.consider_optimizing(cname.as_str(), msg) + self.sess.consider_optimizing(|| self.crate_name(LOCAL_CRATE), msg) } /// Obtain all lang items of this crate and all dependencies (recursively) diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 446ba63ed1c86..12634f67185fd 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -882,10 +882,14 @@ impl Session { /// We want to know if we're allowed to do an optimization for crate foo from -z fuel=foo=n. /// This expends fuel if applicable, and records fuel if applicable. - pub fn consider_optimizing String>(&self, crate_name: &str, msg: T) -> bool { + pub fn consider_optimizing( + &self, + get_crate_name: impl Fn() -> Symbol, + msg: impl Fn() -> String, + ) -> bool { let mut ret = true; if let Some((ref c, _)) = self.opts.unstable_opts.fuel { - if c == crate_name { + if c == get_crate_name().as_str() { assert_eq!(self.threads(), 1); let mut fuel = self.optimization_fuel.lock(); ret = fuel.remaining != 0; @@ -903,7 +907,7 @@ impl Session { } } if let Some(ref c) = self.opts.unstable_opts.print_fuel { - if c == crate_name { + if c == get_crate_name().as_str() { assert_eq!(self.threads(), 1); self.print_fuel.fetch_add(1, SeqCst); } From bc3f6542f39474565f3e7fbe34b9bab45d46789b Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Thu, 2 Mar 2023 16:32:04 +0100 Subject: [PATCH 2/8] Remove manual implementation of str::ne --- library/core/src/str/traits.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index d3ed811b1575b..68f62ce8be5f6 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -28,10 +28,6 @@ impl PartialEq for str { fn eq(&self, other: &str) -> bool { self.as_bytes() == other.as_bytes() } - #[inline] - fn ne(&self, other: &str) -> bool { - !(*self).eq(other) - } } #[stable(feature = "rust1", since = "1.0.0")] From e248d0c8373d960187c92f7e5a7557410036e77d Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Thu, 2 Mar 2023 16:32:23 +0100 Subject: [PATCH 3/8] Remove manual implementation of String::ne --- library/alloc/src/string.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 2b843647dd510..c7e7ed3e95e02 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2213,10 +2213,6 @@ impl PartialEq for String { fn eq(&self, other: &String) -> bool { PartialEq::eq(&self[..], &other[..]) } - #[inline] - fn ne(&self, other: &String) -> bool { - PartialEq::ne(&self[..], &other[..]) - } } macro_rules! impl_eq { From 10a69de5fdc6572e5b4339189c637e5c42f33346 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Thu, 2 Mar 2023 18:33:48 +0000 Subject: [PATCH 4/8] Allow checking whether a type allows being uninitialized This is useful for clippy and for the future `MaybeUninit::assume_init` panics. --- compiler/rustc_const_eval/src/interpret/intrinsics.rs | 1 + .../src/util/check_validity_requirement.rs | 5 ++++- compiler/rustc_middle/src/ty/layout.rs | 7 ++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index c65d677e8ea75..63a041b25a987 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -444,6 +444,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { "aborted execution: attempted to leave type `{}` uninitialized, which is invalid", ty ), + ValidityRequirement::Uninit => bug!("assert_uninit_valid doesn't exist"), }; M::abort(self, msg)?; diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs index dcd15b919f4e3..23fcd22c52b8e 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -30,7 +30,7 @@ pub fn check_validity_requirement<'tcx>( return Ok(!layout.abi.is_uninhabited()); } - if tcx.sess.opts.unstable_opts.strict_init_checks { + if kind == ValidityRequirement::Uninit || tcx.sess.opts.unstable_opts.strict_init_checks { might_permit_raw_init_strict(layout, tcx, kind) } else { let layout_cx = LayoutCx { tcx, param_env: param_env_and_ty.param_env }; @@ -99,6 +99,9 @@ fn might_permit_raw_init_lax<'tcx>( } s.valid_range(cx).contains(val) } + ValidityRequirement::Uninit => { + bug!("ValidityRequirement::Uninit should have been handled above") + } } }; diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 090272a6fa6d9..d9fe01237a733 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -170,13 +170,17 @@ pub const FAT_PTR_EXTRA: usize = 1; /// * Cranelift stores the base-2 log of the lane count in a 4 bit integer. pub const MAX_SIMD_LANES: u64 = 1 << 0xF; -/// Used in `might_permit_raw_init` to indicate the kind of initialisation +/// Used in `check_validity_requirement` to indicate the kind of initialization /// that is checked to be valid #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] pub enum ValidityRequirement { Inhabited, Zero, + /// The return value of mem::uninitialized, 0x01 + /// (unless -Zstrict-init-checks is on, in which case it's the same as Uninit). UninitMitigated0x01Fill, + /// True uninitialized memory. + Uninit, } impl ValidityRequirement { @@ -196,6 +200,7 @@ impl fmt::Display for ValidityRequirement { Self::Inhabited => f.write_str("is inhabited"), Self::Zero => f.write_str("allows being left zeroed"), Self::UninitMitigated0x01Fill => f.write_str("allows being filled with 0x01"), + Self::Uninit => f.write_str("allows being left uninitialized"), } } } From 871ee18086dd77fc42a2f78b225efb73d15d0de7 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 3 Mar 2023 14:33:31 +0900 Subject: [PATCH 5/8] check if snippet is `)` --- compiler/rustc_parse/src/parser/expr.rs | 9 +++++++-- tests/ui/parser/issue-107705.rs | 3 +++ tests/ui/parser/issue-107705.stderr | 10 ++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 tests/ui/parser/issue-107705.rs create mode 100644 tests/ui/parser/issue-107705.stderr diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index b2951e7a1847d..95a7ca80d5d73 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1210,8 +1210,13 @@ impl<'a> Parser<'a> { // `Enum::Foo { a: 3, b: 4 }` or `Enum::Foo(3, 4)`. self.restore_snapshot(snapshot); let close_paren = self.prev_token.span; - let span = lo.to(self.prev_token.span); - if !fields.is_empty() { + let span = lo.to(close_paren); + if !fields.is_empty() && + // `token.kind` should not be compared here. + // This is because the `snapshot.token.kind` is treated as the same as + // that of the open delim in `TokenTreesReader::parse_token_tree`, even if they are different. + self.span_to_snippet(close_paren).map_or(false, |snippet| snippet == ")") + { let mut replacement_err = errors::ParenthesesWithStructFields { span, r#type: path, diff --git a/tests/ui/parser/issue-107705.rs b/tests/ui/parser/issue-107705.rs new file mode 100644 index 0000000000000..b80984fcdb026 --- /dev/null +++ b/tests/ui/parser/issue-107705.rs @@ -0,0 +1,3 @@ +// compile-flags: -C debug-assertions + +fn f() {a(b:&, //~ ERROR this file contains an unclosed delimiter diff --git a/tests/ui/parser/issue-107705.stderr b/tests/ui/parser/issue-107705.stderr new file mode 100644 index 0000000000000..d2d6134611863 --- /dev/null +++ b/tests/ui/parser/issue-107705.stderr @@ -0,0 +1,10 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-107705.rs:3:67 + | +LL | fn f() {a(b:&, + | - - unclosed delimiter ^ + | | + | unclosed delimiter + +error: aborting due to previous error + From 51e976948d6b4c3d16998c83b8ffd1497b0b7d8b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 2 Mar 2023 14:28:06 +0100 Subject: [PATCH 6/8] Emit an error for unclosed generic --- src/librustdoc/html/static/js/search.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 5a46729156d19..b98bced41261c 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -469,6 +469,15 @@ function initSearch(rawSearchIndex) { } const posBefore = parserState.pos; getNextElem(query, parserState, elems, endChar === ">"); + if (endChar !== "") { + if (parserState.pos >= parserState.length) { + throw ["Unclosed ", "<"]; + } + const c2 = parserState.userQuery[parserState.pos]; + if (!isSeparatorCharacter(c2) && c2 !== endChar) { + throw ["Expected ", endChar, ", found ", c2]; + } + } // This case can be encountered if `getNextElem` encountered a "stop character" right // from the start. For example if you have `,,` or `<>`. In this case, we simply move up // the current position to continue the parsing. @@ -477,7 +486,10 @@ function initSearch(rawSearchIndex) { } foundStopChar = false; } - // We are either at the end of the string or on the `endChar`` character, let's move forward + if (parserState.pos >= parserState.length && endChar !== "") { + throw ["Unclosed ", "<"]; + } + // We are either at the end of the string or on the `endChar` character, let's move forward // in any case. parserState.pos += 1; } From 823671589f3de683d6d2f46fa6c0259d08f6cda5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 2 Mar 2023 14:28:15 +0100 Subject: [PATCH 7/8] Add test for unclosed generic --- tests/rustdoc-js-std/parser-errors.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js index 6c5a777028335..98c6f27ca61b8 100644 --- a/tests/rustdoc-js-std/parser-errors.js +++ b/tests/rustdoc-js-std/parser-errors.js @@ -39,6 +39,7 @@ const QUERY = [ "a!!", "mod:a!", "a!::a", + "a<", ]; const PARSED = [ @@ -402,4 +403,13 @@ const PARSED = [ userQuery: "a!::a", error: 'Cannot have associated items in macros', }, + { + elems: [], + foundElems: 0, + original: "a<", + returned: [], + typeFilter: -1, + userQuery: "a<", + error: "Unclosed `<`", + }, ]; From 7fe4f0701c34fd107101a6bdb2d62e0935d798a4 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 4 Mar 2023 07:54:29 +0200 Subject: [PATCH 8/8] rustc_expand: make proc-macro derive error translatable --- compiler/rustc_expand/locales/en-US.ftl | 3 +++ compiler/rustc_expand/src/errors.rs | 7 +++++++ compiler/rustc_expand/src/proc_macro.rs | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_expand/locales/en-US.ftl b/compiler/rustc_expand/locales/en-US.ftl index b475d285f6b7e..cfae781bdee5f 100644 --- a/compiler/rustc_expand/locales/en-US.ftl +++ b/compiler/rustc_expand/locales/en-US.ftl @@ -133,3 +133,6 @@ expand_trace_macro = trace_macro expand_proc_macro_panicked = proc macro panicked .help = message: {$message} + +expand_proc_macro_derive_tokens = + proc-macro derive produced unparseable tokens diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index 70ab222b48470..e5102a952e741 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -390,3 +390,10 @@ pub(crate) struct ProcMacroPanicked { pub(crate) struct ProcMacroPanickedHelp { pub message: String, } + +#[derive(Diagnostic)] +#[diag(expand_proc_macro_derive_tokens)] +pub struct ProcMacroDeriveTokens { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index cef64a1047902..ddba14417195b 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -176,7 +176,7 @@ impl MultiItemModifier for DeriveProcMacro { // fail if there have been errors emitted if ecx.sess.parse_sess.span_diagnostic.err_count() > error_count_before { - ecx.struct_span_err(span, "proc-macro derive produced unparseable tokens").emit(); + ecx.sess.emit_err(errors::ProcMacroDeriveTokens { span }); } ExpandResult::Ready(items)