diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 9ad945359b6b3..a29cdade02343 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_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) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index e9e121f9c9b04..d9af2fd74cee5 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -794,8 +794,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_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 9a517d2d2b425..254ffc33c96f0 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"), } } } 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/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); } 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 { 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")] 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; } 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 `<`", + }, ]; 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 +