diff --git a/Cargo.lock b/Cargo.lock index a838c0775b7b8..0f42738ecbf4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,9 +80,9 @@ dependencies = [ [[package]] name = "annotate-snippets" -version = "0.12.7" +version = "0.12.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47224528f74de27d1d06aad6a5dda4f865b6ebe2e56c538943d746a7270cb67e" +checksum = "025c7edcdffa4ccc5c0905f472a0ae3759378cfbef88ef518a3575e19ae3aebd" dependencies = [ "anstyle", "unicode-width 0.2.2", @@ -3766,7 +3766,7 @@ dependencies = [ name = "rustc_errors" version = "0.0.0" dependencies = [ - "annotate-snippets 0.12.7", + "annotate-snippets 0.12.8", "anstream", "anstyle", "derive_setters", diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index 6ade87ea3b255..6606092e421eb 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start -annotate-snippets = "0.12.7" +annotate-snippets = "0.12.8" anstream = "0.6.20" anstyle = "1.0.13" derive_setters = "0.1.6" diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 854e3ddf15e4a..5d22a8b8e30ab 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -329,7 +329,7 @@ impl AnnotateSnippetEmitter { let substitutions = suggestion .substitutions .into_iter() - .filter_map(|mut subst| { + .filter(|subst| { // Suggestions coming from macros can have malformed spans. This is a heavy // handed approach to avoid ICEs by ignoring the suggestion outright. let invalid = @@ -337,12 +337,14 @@ impl AnnotateSnippetEmitter { if invalid { debug!("suggestion contains an invalid span: {:?}", subst); } - + !invalid + }) + .filter_map(|mut subst| { // Assumption: all spans are in the same file, and all spans // are disjoint. Sort in ascending order. subst.parts.sort_by_key(|part| part.span.lo()); // Verify the assumption that all spans are disjoint - assert_eq!( + debug_assert_eq!( subst.parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)), None, "all spans must be disjoint", @@ -355,13 +357,11 @@ impl AnnotateSnippetEmitter { let item_span = subst.parts.first()?; let file = sm.lookup_source_file(item_span.span.lo()); - if !invalid - && should_show_source_code( - &self.ignored_directories_in_source_blocks, - sm, - &file, - ) - { + if should_show_source_code( + &self.ignored_directories_in_source_blocks, + sm, + &file, + ) { Some(subst) } else { None diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index d98d6e563645c..81a7ee1ff45fe 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -47,15 +47,16 @@ const DEFAULT_COLUMN_WIDTH: usize = 140; /// Describes the way the content of the `rendered` field of the json output is generated #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum HumanReadableErrorType { - Default, - Unicode, - AnnotateSnippet, - Short, + Default { short: bool }, + AnnotateSnippet { short: bool, unicode: bool }, } impl HumanReadableErrorType { pub fn short(&self) -> bool { - *self == HumanReadableErrorType::Short + match self { + HumanReadableErrorType::Default { short } + | HumanReadableErrorType::AnnotateSnippet { short, .. } => *short, + } } } diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 03ce1d82ef3c4..ce5c830bbfcd6 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -25,6 +25,7 @@ use rustc_span::hygiene::ExpnData; use rustc_span::source_map::{FilePathMapping, SourceMap}; use serde::Serialize; +use crate::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use crate::diagnostic::IsLint; use crate::emitter::{ ColorConfig, Destination, Emitter, HumanEmitter, HumanReadableErrorType, OutputTheme, @@ -370,7 +371,6 @@ impl Diagnostic { .insert(0, Diagnostic::from_sub_diagnostic(&diag.emitted_at_sub_diag(), &args, je)); } let buf = BufWriter(Arc::new(Mutex::new(Vec::new()))); - let short = je.json_rendered.short(); let dst: Destination = AutoStream::new( Box::new(buf.clone()), match je.color_config.to_color_choice() { @@ -378,21 +378,39 @@ impl Diagnostic { choice => choice, }, ); - HumanEmitter::new(dst, je.translator.clone()) - .short_message(short) - .sm(je.sm.clone()) - .diagnostic_width(je.diagnostic_width) - .macro_backtrace(je.macro_backtrace) - .track_diagnostics(je.track_diagnostics) - .terminal_url(je.terminal_url) - .ui_testing(je.ui_testing) - .ignored_directories_in_source_blocks(je.ignored_directories_in_source_blocks.clone()) - .theme(if let HumanReadableErrorType::Unicode = je.json_rendered { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) - .emit_diagnostic(diag, registry); + match je.json_rendered { + HumanReadableErrorType::AnnotateSnippet { short, unicode } => { + AnnotateSnippetEmitter::new(dst, je.translator.clone()) + .short_message(short) + .sm(je.sm.clone()) + .diagnostic_width(je.diagnostic_width) + .macro_backtrace(je.macro_backtrace) + .track_diagnostics(je.track_diagnostics) + .terminal_url(je.terminal_url) + .ui_testing(je.ui_testing) + .ignored_directories_in_source_blocks( + je.ignored_directories_in_source_blocks.clone(), + ) + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) + .emit_diagnostic(diag, registry) + } + HumanReadableErrorType::Default { short } => { + HumanEmitter::new(dst, je.translator.clone()) + .short_message(short) + .sm(je.sm.clone()) + .diagnostic_width(je.diagnostic_width) + .macro_backtrace(je.macro_backtrace) + .track_diagnostics(je.track_diagnostics) + .terminal_url(je.terminal_url) + .ui_testing(je.ui_testing) + .ignored_directories_in_source_blocks( + je.ignored_directories_in_source_blocks.clone(), + ) + .theme(OutputTheme::Ascii) + .emit_diagnostic(diag, registry) + } + } + let buf = Arc::try_unwrap(buf.0).unwrap().into_inner().unwrap(); let buf = String::from_utf8(buf).unwrap(); diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index 8cf81f467d84c..79bb5054dfeff 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -50,7 +50,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { Some(sm), translator, true, // pretty - HumanReadableErrorType::Short, + HumanReadableErrorType::Default { short: true }, ColorConfig::Never, ); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 6c08b37dec083..9848b11ce8140 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -321,7 +321,7 @@ fn test_search_paths_tracking_hash_different_order() { let early_dcx = EarlyDiagCtxt::new(JSON); const JSON: ErrorOutputType = ErrorOutputType::Json { pretty: false, - json_rendered: HumanReadableErrorType::Default, + json_rendered: HumanReadableErrorType::Default { short: false }, color_config: ColorConfig::Never, }; diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index b9a6f67ab0dcc..2e64fc290fcc2 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -698,6 +698,7 @@ impl<'tcx> FallibleTypeFolder> for MakeSuggestableFolder<'tcx> { } Closure(..) + | CoroutineClosure(..) | FnDef(..) | Infer(..) | Coroutine(..) diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index c9a42dddac42b..221593d6eadb5 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -454,7 +454,16 @@ where self.assemble_object_bound_candidates(goal, &mut candidates); } } - AssembleCandidatesFrom::EnvAndBounds => {} + AssembleCandidatesFrom::EnvAndBounds => { + // This is somewhat inconsistent and may make #57893 slightly easier to exploit. + // However, it matches the behavior of the old solver. See + // `tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs`. + if matches!(normalized_self_ty.kind(), ty::Dynamic(..)) + && !candidates.iter().any(|c| matches!(c.source, CandidateSource::ParamEnv(_))) + { + self.assemble_object_bound_candidates(goal, &mut candidates); + } + } } (candidates, failed_candidate_info) diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index 5fe921da13817..9b157cb6c7bf9 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -1,5 +1,4 @@ #![allow(rustc::symbol_intern_string_literal)] - use std::assert_matches::assert_matches; use std::io::prelude::*; use std::iter::Peekable; @@ -12,6 +11,7 @@ use rustc_ast::token::{self, Delimiter, Token}; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_ast::{self as ast, PatKind, visit}; use rustc_ast_pretty::pprust::item_to_string; +use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::emitter::{HumanEmitter, OutputTheme}; use rustc_errors::translation::Translator; use rustc_errors::{AutoStream, DiagCtxt, MultiSpan, PResult}; @@ -43,12 +43,22 @@ fn create_test_handler(theme: OutputTheme) -> (DiagCtxt, Arc, Arc = Box::new(Shared { data: output.clone() }); + let auto_stream = AutoStream::never(shared); + let dcx = DiagCtxt::new(match theme { + OutputTheme::Ascii => Box::new( + HumanEmitter::new(auto_stream, translator) + .sm(Some(source_map.clone())) + .diagnostic_width(Some(140)) + .theme(theme), + ), + OutputTheme::Unicode => Box::new( + AnnotateSnippetEmitter::new(auto_stream, translator) + .sm(Some(source_map.clone())) + .diagnostic_width(Some(140)) + .theme(theme), + ), + }); (dcx, source_map, output) } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index ce6f6434e793d..3403745084c58 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -826,7 +826,7 @@ pub enum ErrorOutputType { /// Output meant for the consumption of humans. #[default] HumanReadable { - kind: HumanReadableErrorType = HumanReadableErrorType::Default, + kind: HumanReadableErrorType = HumanReadableErrorType::Default { short: false }, color_config: ColorConfig = ColorConfig::Auto, }, /// Output that's consumed by other tools such as `rustfix` or the `RLS`. @@ -2041,8 +2041,16 @@ impl JsonUnusedExterns { /// /// The first value returned is how to render JSON diagnostics, and the second /// is whether or not artifact notifications are enabled. -pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> JsonConfig { - let mut json_rendered = HumanReadableErrorType::Default; +pub fn parse_json( + early_dcx: &EarlyDiagCtxt, + matches: &getopts::Matches, + is_nightly_build: bool, +) -> JsonConfig { + let mut json_rendered = if is_nightly_build { + HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false } + } else { + HumanReadableErrorType::Default { short: false } + }; let mut json_color = ColorConfig::Never; let mut json_artifact_notifications = false; let mut json_unused_externs = JsonUnusedExterns::No; @@ -2058,9 +2066,16 @@ pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Json for sub_option in option.split(',') { match sub_option { - "diagnostic-short" => json_rendered = HumanReadableErrorType::Short, + "diagnostic-short" => { + json_rendered = if is_nightly_build { + HumanReadableErrorType::AnnotateSnippet { short: true, unicode: false } + } else { + HumanReadableErrorType::Default { short: true } + }; + } "diagnostic-unicode" => { - json_rendered = HumanReadableErrorType::Unicode; + json_rendered = + HumanReadableErrorType::AnnotateSnippet { short: false, unicode: true }; } "diagnostic-rendered-ansi" => json_color = ColorConfig::Always, "artifacts" => json_artifact_notifications = true, @@ -2090,16 +2105,24 @@ pub fn parse_error_format( color_config: ColorConfig, json_color: ColorConfig, json_rendered: HumanReadableErrorType, + is_nightly_build: bool, ) -> ErrorOutputType { + let default_kind = if is_nightly_build { + HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false } + } else { + HumanReadableErrorType::Default { short: false } + }; // We need the `opts_present` check because the driver will send us Matches // with only stable options if no unstable options are used. Since error-format // is unstable, it will not be present. We have to use `opts_present` not // `opt_present` because the latter will panic. let error_format = if matches.opts_present(&["error-format".to_owned()]) { match matches.opt_str("error-format").as_deref() { - None | Some("human") => ErrorOutputType::HumanReadable { color_config, .. }, + None | Some("human") => { + ErrorOutputType::HumanReadable { color_config, kind: default_kind } + } Some("human-annotate-rs") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType::AnnotateSnippet, + kind: HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false }, color_config, }, Some("json") => { @@ -2108,15 +2131,23 @@ pub fn parse_error_format( Some("pretty-json") => { ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color } } - Some("short") => { - ErrorOutputType::HumanReadable { kind: HumanReadableErrorType::Short, color_config } - } + Some("short") => ErrorOutputType::HumanReadable { + kind: if is_nightly_build { + HumanReadableErrorType::AnnotateSnippet { short: true, unicode: false } + } else { + HumanReadableErrorType::Default { short: true } + }, + color_config, + }, Some("human-unicode") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType::Unicode, + kind: HumanReadableErrorType::AnnotateSnippet { short: false, unicode: true }, color_config, }, Some(arg) => { - early_dcx.set_error_format(ErrorOutputType::HumanReadable { color_config, .. }); + early_dcx.set_error_format(ErrorOutputType::HumanReadable { + color_config, + kind: default_kind, + }); early_dcx.early_fatal(format!( "argument for `--error-format` must be `human`, `human-annotate-rs`, \ `human-unicode`, `json`, `pretty-json` or `short` (instead was `{arg}`)" @@ -2124,7 +2155,7 @@ pub fn parse_error_format( } } } else { - ErrorOutputType::HumanReadable { color_config, .. } + ErrorOutputType::HumanReadable { color_config, kind: default_kind } }; match error_format { @@ -2172,16 +2203,17 @@ pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches fn check_error_format_stability( early_dcx: &EarlyDiagCtxt, unstable_opts: &UnstableOptions, + is_nightly_build: bool, format: ErrorOutputType, ) { - if unstable_opts.unstable_options { + if unstable_opts.unstable_options || is_nightly_build { return; } let format = match format { ErrorOutputType::Json { pretty: true, .. } => "pretty-json", ErrorOutputType::HumanReadable { kind, .. } => match kind { - HumanReadableErrorType::AnnotateSnippet => "human-annotate-rs", - HumanReadableErrorType::Unicode => "human-unicode", + HumanReadableErrorType::AnnotateSnippet { unicode: false, .. } => "human-annotate-rs", + HumanReadableErrorType::AnnotateSnippet { unicode: true, .. } => "human-unicode", _ => return, }, _ => return, @@ -2602,6 +2634,8 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let edition = parse_crate_edition(early_dcx, matches); + let crate_name = matches.opt_str("crate-name"); + let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref()); let JsonConfig { json_rendered, json_color, @@ -2609,9 +2643,16 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M json_timings, json_unused_externs, json_future_incompat, - } = parse_json(early_dcx, matches); + } = parse_json(early_dcx, matches, unstable_features.is_nightly_build()); - let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered); + let error_format = parse_error_format( + early_dcx, + matches, + color, + json_color, + json_rendered, + unstable_features.is_nightly_build(), + ); early_dcx.set_error_format(error_format); @@ -2632,7 +2673,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M early_dcx.early_fatal("--json=timings is unstable and requires using `-Zunstable-options`"); } - check_error_format_stability(early_dcx, &unstable_opts, error_format); + check_error_format_stability( + early_dcx, + &unstable_opts, + unstable_features.is_nightly_build(), + error_format, + ); let output_types = parse_output_types(early_dcx, &unstable_opts, matches); @@ -2819,8 +2865,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M ) } - let crate_name = matches.opt_str("crate-name"); - let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref()); // Parse any `-l` flags, which link to native libraries. let libs = parse_native_libs(early_dcx, &unstable_opts, unstable_features, matches); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 0f8f260cb820f..9fb3c35d5ef73 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -954,10 +954,8 @@ fn default_emitter( let source_map = if sopts.unstable_opts.link_only { None } else { Some(source_map) }; match sopts.error_format { - config::ErrorOutputType::HumanReadable { kind, color_config } => { - let short = kind.short(); - - if let HumanReadableErrorType::AnnotateSnippet = kind { + config::ErrorOutputType::HumanReadable { kind, color_config } => match kind { + HumanReadableErrorType::AnnotateSnippet { short, unicode } => { let emitter = AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) .sm(source_map) @@ -966,11 +964,7 @@ fn default_emitter( .macro_backtrace(macro_backtrace) .track_diagnostics(track_diagnostics) .terminal_url(terminal_url) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) .ignored_directories_in_source_blocks( sopts .unstable_opts @@ -978,7 +972,8 @@ fn default_emitter( .clone(), ); Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing)) - } else { + } + HumanReadableErrorType::Default { short } => { let emitter = HumanEmitter::new(stderr_destination(color_config), translator) .sm(source_map) .short_message(short) @@ -986,17 +981,13 @@ fn default_emitter( .macro_backtrace(macro_backtrace) .track_diagnostics(track_diagnostics) .terminal_url(terminal_url) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(OutputTheme::Ascii) .ignored_directories_in_source_blocks( sopts.unstable_opts.ignore_directory_in_diagnostics_source_blocks.clone(), ); Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing)) } - } + }, config::ErrorOutputType::Json { pretty, json_rendered, color_config } => Box::new( JsonEmitter::new( Box::new(io::BufWriter::new(io::stderr())), @@ -1503,18 +1494,18 @@ fn mk_emitter(output: ErrorOutputType) -> Box { let translator = Translator::with_fallback_bundle(vec![rustc_errors::DEFAULT_LOCALE_RESOURCE], false); let emitter: Box = match output { - config::ErrorOutputType::HumanReadable { kind, color_config } => { - let short = kind.short(); - Box::new( + config::ErrorOutputType::HumanReadable { kind, color_config } => match kind { + HumanReadableErrorType::AnnotateSnippet { short, unicode } => Box::new( + AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) + .short_message(short), + ), + HumanReadableErrorType::Default { short } => Box::new( HumanEmitter::new(stderr_destination(color_config), translator) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(OutputTheme::Ascii) .short_message(short), - ) - } + ), + }, config::ErrorOutputType::Json { pretty, json_rendered, color_config } => { Box::new(JsonEmitter::new( Box::new(io::BufWriter::new(io::stderr())), diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index dc5aaa8726032..a85c874d54de1 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -52,7 +52,7 @@ pub use self::iter::Iter; mod iter; -use self::spec_extend::SpecExtend; +use self::spec_extend::{SpecExtend, SpecExtendFront}; mod spec_extend; @@ -179,6 +179,21 @@ impl VecDeque { self.len += 1; } + /// Prepends an element to the buffer. + /// + /// # Safety + /// + /// May only be called if `deque.len() < deque.capacity()` + #[inline] + unsafe fn push_front_unchecked(&mut self, element: T) { + self.head = self.wrap_sub(self.head, 1); + // SAFETY: Because of the precondition, it's guaranteed that there is space + // in the logical array before the first element (where self.head is now). + unsafe { self.buffer_write(self.head, element) }; + // This can't overflow because `deque.len() < deque.capacity() <= usize::MAX`. + self.len += 1; + } + /// Moves an element out of the buffer #[inline] unsafe fn buffer_read(&mut self, off: usize) -> T { @@ -505,6 +520,35 @@ impl VecDeque { } } + /// Copies all values from `src` to `dst` in reversed order, wrapping around if needed. + /// Assumes capacity is sufficient. + /// Equivalent to calling [`VecDeque::copy_slice`] with a [reversed](https://doc.rust-lang.org/std/primitive.slice.html#method.reverse) slice. + #[inline] + unsafe fn copy_slice_reversed(&mut self, dst: usize, src: &[T]) { + /// # Safety + /// + /// See [`ptr::copy_nonoverlapping`]. + unsafe fn copy_nonoverlapping_reversed(src: *const T, dst: *mut T, count: usize) { + for i in 0..count { + unsafe { ptr::copy_nonoverlapping(src.add(count - 1 - i), dst.add(i), 1) }; + } + } + + debug_assert!(src.len() <= self.capacity()); + let head_room = self.capacity() - dst; + if src.len() <= head_room { + unsafe { + copy_nonoverlapping_reversed(src.as_ptr(), self.ptr().add(dst), src.len()); + } + } else { + let (left, right) = src.split_at(src.len() - head_room); + unsafe { + copy_nonoverlapping_reversed(right.as_ptr(), self.ptr().add(dst), right.len()); + copy_nonoverlapping_reversed(left.as_ptr(), self.ptr(), left.len()); + } + } + } + /// Writes all values from `iter` to `dst`. /// /// # Safety @@ -2122,6 +2166,73 @@ impl VecDeque { unsafe { self.buffer_write(self.to_physical_idx(len), value) } } + /// Prepends all contents of the iterator to the front of the deque. + /// The order of the contents is preserved. + /// + /// To get behavior like [`append`][VecDeque::append] where elements are moved + /// from the other collection to this one, use `self.prepend(other.drain(..))`. + /// + /// # Examples + /// + /// ``` + /// #![feature(deque_extend_front)] + /// use std::collections::VecDeque; + /// + /// let mut deque = VecDeque::from([4, 5, 6]); + /// deque.prepend([1, 2, 3]); + /// assert_eq!(deque, [1, 2, 3, 4, 5, 6]); + /// ``` + /// + /// Move values between collections like [`append`][VecDeque::append] does but prepend to the front: + /// + /// ``` + /// #![feature(deque_extend_front)] + /// use std::collections::VecDeque; + /// + /// let mut deque1 = VecDeque::from([4, 5, 6]); + /// let mut deque2 = VecDeque::from([1, 2, 3]); + /// deque1.prepend(deque2.drain(..)); + /// assert_eq!(deque1, [1, 2, 3, 4, 5, 6]); + /// assert!(deque2.is_empty()); + /// ``` + #[unstable(feature = "deque_extend_front", issue = "146975")] + #[track_caller] + pub fn prepend>(&mut self, other: I) { + self.extend_front(other.into_iter().rev()) + } + + /// Prepends all contents of the iterator to the front of the deque, + /// as if [`push_front`][VecDeque::push_front] was called repeatedly with + /// the values yielded by the iterator. + /// + /// # Examples + /// + /// ``` + /// #![feature(deque_extend_front)] + /// use std::collections::VecDeque; + /// + /// let mut deque = VecDeque::from([4, 5, 6]); + /// deque.extend_front([3, 2, 1]); + /// assert_eq!(deque, [1, 2, 3, 4, 5, 6]); + /// ``` + /// + /// This behaves like [`push_front`][VecDeque::push_front] was called repeatedly: + /// + /// ``` + /// use std::collections::VecDeque; + /// + /// let mut deque = VecDeque::from([4, 5, 6]); + /// for v in [3, 2, 1] { + /// deque.push_front(v); + /// } + /// assert_eq!(deque, [1, 2, 3, 4, 5, 6]); + /// ``` + #[unstable(feature = "deque_extend_front", issue = "146975")] + #[track_caller] + pub fn extend_front>(&mut self, iter: I) { + >::spec_extend_front(self, iter.into_iter()); + } + #[inline] fn is_contiguous(&self) -> bool { // Do the calculation like this to avoid overflowing if len + head > usize::MAX diff --git a/library/alloc/src/collections/vec_deque/spec_extend.rs b/library/alloc/src/collections/vec_deque/spec_extend.rs index 6c2199135e08a..f73ba795cbea4 100644 --- a/library/alloc/src/collections/vec_deque/spec_extend.rs +++ b/library/alloc/src/collections/vec_deque/spec_extend.rs @@ -1,4 +1,4 @@ -use core::iter::TrustedLen; +use core::iter::{Copied, Rev, TrustedLen}; use core::slice; use super::VecDeque; @@ -114,3 +114,113 @@ where } } } + +// Specialization trait used for VecDeque::extend_front +pub(super) trait SpecExtendFront { + #[track_caller] + fn spec_extend_front(&mut self, iter: I); +} + +impl SpecExtendFront for VecDeque +where + I: Iterator, +{ + #[track_caller] + default fn spec_extend_front(&mut self, mut iter: I) { + // This function should be the moral equivalent of: + // + // for item in iter { + // self.push_front(item); + // } + + while let Some(element) = iter.next() { + let (lower, _) = iter.size_hint(); + self.reserve(lower.saturating_add(1)); + + // SAFETY: We just reserved space for at least one element. + unsafe { self.push_front_unchecked(element) }; + + // Inner loop to avoid repeatedly calling `reserve`. + while self.len < self.capacity() { + let Some(element) = iter.next() else { + return; + }; + // SAFETY: The loop condition guarantees that `self.len() < self.capacity()`. + unsafe { self.push_front_unchecked(element) }; + } + } + } +} + +#[cfg(not(test))] +impl SpecExtendFront> for VecDeque { + #[track_caller] + fn spec_extend_front(&mut self, mut iterator: vec::IntoIter) { + let slice = iterator.as_slice(); + // SAFETY: elements in the slice are forgotten after this call + unsafe { prepend_reversed(self, slice) }; + iterator.forget_remaining_elements(); + } +} + +#[cfg(not(test))] +impl SpecExtendFront>> for VecDeque { + #[track_caller] + fn spec_extend_front(&mut self, iterator: Rev>) { + let mut iterator = iterator.into_inner(); + let slice = iterator.as_slice(); + // SAFETY: elements in the slice are forgotten after this call + unsafe { prepend(self, slice) }; + iterator.forget_remaining_elements(); + } +} + +impl<'a, T, A: Allocator> SpecExtendFront>> for VecDeque +where + Copied>: Iterator, +{ + #[track_caller] + fn spec_extend_front(&mut self, iter: Copied>) { + let slice = iter.into_inner().as_slice(); + // SAFETY: T is Copy because Copied> is Iterator + unsafe { prepend_reversed(self, slice) }; + } +} + +impl<'a, T, A: Allocator> SpecExtendFront>>> for VecDeque +where + Rev>>: Iterator, +{ + #[track_caller] + fn spec_extend_front(&mut self, iter: Rev>>) { + let slice = iter.into_inner().into_inner().as_slice(); + // SAFETY: T is Copy because Rev>> is Iterator + unsafe { prepend(self, slice) }; + } +} + +/// # Safety +/// +/// Elements of `slice` will be copied into the deque, make sure to forget the items if `T` is not `Copy`. +unsafe fn prepend(deque: &mut VecDeque, slice: &[T]) { + deque.reserve(slice.len()); + + unsafe { + deque.head = deque.wrap_sub(deque.head, slice.len()); + deque.copy_slice(deque.head, slice); + deque.len += slice.len(); + } +} + +/// # Safety +/// +/// Elements of `slice` will be copied into the deque, make sure to forget the items if `T` is not `Copy`. +unsafe fn prepend_reversed(deque: &mut VecDeque, slice: &[T]) { + deque.reserve(slice.len()); + + unsafe { + deque.head = deque.wrap_sub(deque.head, slice.len()); + deque.copy_slice_reversed(deque.head, slice); + deque.len += slice.len(); + } +} diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 786f88c29ef46..73197d021f1a3 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -106,6 +106,7 @@ #![feature(const_default)] #![feature(const_eval_select)] #![feature(const_heap)] +#![feature(copied_into_inner)] #![feature(core_intrinsics)] #![feature(deprecated_suggestion)] #![feature(deref_pure_trait)] @@ -134,6 +135,7 @@ #![feature(ptr_alignment_type)] #![feature(ptr_internals)] #![feature(ptr_metadata)] +#![feature(rev_into_inner)] #![feature(set_ptr_value)] #![feature(sized_type_properties)] #![feature(slice_from_ptr_range)] diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index 0201c8752210c..efdcb893bfeef 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -20,6 +20,7 @@ #![feature(assert_matches)] #![feature(char_internals)] #![feature(char_max_len)] +#![feature(copied_into_inner)] #![feature(core_intrinsics)] #![feature(exact_size_is_empty)] #![feature(extend_one)] @@ -32,6 +33,7 @@ #![feature(maybe_uninit_uninit_array_transpose)] #![feature(ptr_alignment_type)] #![feature(ptr_internals)] +#![feature(rev_into_inner)] #![feature(sized_type_properties)] #![feature(slice_iter_mut_as_mut_slice)] #![feature(slice_ptr_get)] diff --git a/library/alloctests/tests/vec_deque.rs b/library/alloctests/tests/vec_deque.rs index 0a4a0e0cac4d7..cf31613577f74 100644 --- a/library/alloctests/tests/vec_deque.rs +++ b/library/alloctests/tests/vec_deque.rs @@ -2081,3 +2081,77 @@ fn test_extend_and_prepend_from_within() { v.extend_from_within(..); assert_eq!(v.iter().map(|s| &**s).collect::(), "123123123123"); } + +#[test] +fn test_extend_front() { + let mut v = VecDeque::new(); + v.extend_front(0..3); + assert_eq!(v, [2, 1, 0]); + v.extend_front(3..6); + assert_eq!(v, [5, 4, 3, 2, 1, 0]); + v.prepend([1; 4]); + assert_eq!(v, [1, 1, 1, 1, 5, 4, 3, 2, 1, 0]); + + let mut v = VecDeque::with_capacity(8); + let cap = v.capacity(); + v.extend(0..4); + v.truncate_front(2); + v.extend_front(4..8); + assert_eq!(v.as_slices(), ([7, 6].as_slice(), [5, 4, 2, 3].as_slice())); + assert_eq!(v.capacity(), cap); + + let mut v = VecDeque::new(); + v.extend_front([]); + v.extend_front(None); + v.extend_front(vec![]); + v.prepend([]); + v.prepend(None); + v.prepend(vec![]); + assert_eq!(v.capacity(), 0); + v.extend_front(Some(123)); + assert_eq!(v, [123]); +} + +#[test] +fn test_extend_front_specialization_vec_into_iter() { + // trigger 4 code paths: all combinations of prepend and extend_front, wrap and no wrap + let mut v = VecDeque::with_capacity(4); + v.prepend(vec![1, 2, 3]); + assert_eq!(v, [1, 2, 3]); + v.pop_back(); + // this should wrap around the physical buffer + v.prepend(vec![-1, 0]); + // check it really wrapped + assert_eq!(v.as_slices(), ([-1].as_slice(), [0, 1, 2].as_slice())); + + let mut v = VecDeque::with_capacity(4); + v.extend_front(vec![1, 2, 3]); + assert_eq!(v, [3, 2, 1]); + v.pop_back(); + // this should wrap around the physical buffer + v.extend_front(vec![4, 5]); + // check it really wrapped + assert_eq!(v.as_slices(), ([5].as_slice(), [4, 3, 2].as_slice())); +} + +#[test] +fn test_extend_front_specialization_copy_slice() { + // trigger 4 code paths: all combinations of prepend and extend_front, wrap and no wrap + let mut v = VecDeque::with_capacity(4); + v.prepend([1, 2, 3].as_slice().iter().copied()); + assert_eq!(v, [1, 2, 3]); + v.pop_back(); + // this should wrap around the physical buffer + v.prepend([-1, 0].as_slice().iter().copied()); + // check it really wrapped + assert_eq!(v.as_slices(), ([-1].as_slice(), [0, 1, 2].as_slice())); + + let mut v = VecDeque::with_capacity(4); + v.extend_front([1, 2, 3].as_slice().iter().copied()); + assert_eq!(v, [3, 2, 1]); + v.pop_back(); + // this should wrap around the physical buffer + v.extend_front([4, 5].as_slice().iter().copied()); + // check it really wrapped + assert_eq!(v.as_slices(), ([5].as_slice(), [4, 3, 2].as_slice())); +} diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index 23e4e25ab5388..9627ace29795c 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -24,6 +24,12 @@ impl Copied { pub(in crate::iter) fn new(it: I) -> Copied { Copied { it } } + + #[doc(hidden)] + #[unstable(feature = "copied_into_inner", issue = "none")] + pub fn into_inner(self) -> I { + self.it + } } fn copy_fold(mut f: impl FnMut(Acc, T) -> Acc) -> impl FnMut(Acc, &T) -> Acc { diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 55e04671b83ca..da19f506a3700 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -389,10 +389,19 @@ impl Options { } let color = config::parse_color(early_dcx, matches); + let crate_name = matches.opt_str("crate-name"); + let unstable_features = + rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref()); let config::JsonConfig { json_rendered, json_unused_externs, json_color, .. } = - config::parse_json(early_dcx, matches); - let error_format = - config::parse_error_format(early_dcx, matches, color, json_color, json_rendered); + config::parse_json(early_dcx, matches, unstable_features.is_nightly_build()); + let error_format = config::parse_error_format( + early_dcx, + matches, + color, + json_color, + json_rendered, + unstable_features.is_nightly_build(), + ); let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_default(); let mut target_modifiers = BTreeMap::::new(); @@ -753,7 +762,6 @@ impl Options { } }; - let crate_name = matches.opt_str("crate-name"); let bin_crate = crate_types.contains(&CrateType::Executable); let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro); let playground_url = matches.opt_str("playground-url"); @@ -815,9 +823,6 @@ impl Options { crate::scrape_examples::load_call_locations(with_examples, dcx, &mut loaded_paths); let doctest_build_args = matches.opt_strs("doctest-build-arg"); - let unstable_features = - rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref()); - let disable_minification = matches.opt_present("disable-minification"); let options = Options { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 44bac8197539b..451d0b4f5be91 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -5,6 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::unord::UnordSet; use rustc_driver::USING_INTERNAL_FEATURES; use rustc_errors::TerminalUrl; +use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::codes::*; use rustc_errors::emitter::{ DynEmitter, HumanEmitter, HumanReadableErrorType, OutputTheme, stderr_destination, @@ -152,22 +153,26 @@ pub(crate) fn new_dcx( ) -> rustc_errors::DiagCtxt { let translator = rustc_driver::default_translator(); let emitter: Box = match error_format { - ErrorOutputType::HumanReadable { kind, color_config } => { - let short = kind.short(); - Box::new( + ErrorOutputType::HumanReadable { kind, color_config } => match kind { + HumanReadableErrorType::AnnotateSnippet { short, unicode } => Box::new( + AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) + .sm(source_map.map(|sm| sm as _)) + .short_message(short) + .diagnostic_width(diagnostic_width) + .track_diagnostics(unstable_opts.track_diagnostics) + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) + .ui_testing(unstable_opts.ui_testing), + ), + HumanReadableErrorType::Default { short } => Box::new( HumanEmitter::new(stderr_destination(color_config), translator) .sm(source_map.map(|sm| sm as _)) .short_message(short) .diagnostic_width(diagnostic_width) .track_diagnostics(unstable_opts.track_diagnostics) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(OutputTheme::Ascii) .ui_testing(unstable_opts.ui_testing), - ) - } + ), + }, ErrorOutputType::Json { pretty, json_rendered, color_config } => { let source_map = source_map.unwrap_or_else(|| { Arc::new(source_map::SourceMap::new(source_map::FilePathMapping::empty())) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index a8d5ed9fa7361..481aa392007c8 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -600,7 +600,7 @@ fn run_test( ]); if let ErrorOutputType::HumanReadable { kind, color_config } = rustdoc_options.error_format { let short = kind.short(); - let unicode = kind == HumanReadableErrorType::Unicode; + let unicode = kind == HumanReadableErrorType::AnnotateSnippet { unicode: true, short }; if short { compiler_args.extend_from_slice(&["--error-format".to_owned(), "short".to_owned()]); diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 0363418f91647..5e42bb9861bfa 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -427,6 +427,27 @@ impl<'a, F: Write> TokenHandler<'a, '_, F> { } } } + + /// Used when we're done with the current expansion "original code" (ie code before expansion). + /// We close all tags inside `Class::Original` and only keep the ones that were not closed yet. + fn close_original_tag(&mut self) { + let mut classes_to_reopen = Vec::new(); + while let Some(mut class_info) = self.class_stack.open_classes.pop() { + if class_info.class == Class::Original { + while let Some(class_info) = classes_to_reopen.pop() { + self.class_stack.open_classes.push(class_info); + } + class_info.close_tag(self.out); + return; + } + class_info.close_tag(self.out); + if !class_info.pending_exit { + class_info.closing_tag = None; + classes_to_reopen.push(class_info); + } + } + panic!("Didn't find `Class::Original` to close"); + } } impl Drop for TokenHandler<'_, '_, F> { @@ -484,7 +505,9 @@ fn end_expansion<'a, W: Write>( expanded_codes: &'a [ExpandedCode], span: Span, ) -> Option<&'a ExpandedCode> { - token_handler.class_stack.exit_elem(); + // We close `Class::Original` and everything open inside it. + token_handler.close_original_tag(); + // Then we check if we have another macro expansion on the same line. let expansion = get_next_expansion(expanded_codes, token_handler.line, span); if expansion.is_none() { token_handler.close_expansion(); diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 96e941b598ad1..9c072eed51aec 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -1051,28 +1051,21 @@ impl Serialize for TypeData { where S: Serializer, { - if self.search_unbox - || !self.inverted_function_inputs_index.is_empty() - || !self.inverted_function_output_index.is_empty() - { - let mut seq = serializer.serialize_seq(None)?; - let mut buf = Vec::new(); - encode::write_postings_to_string(&self.inverted_function_inputs_index, &mut buf); - let mut serialized_result = Vec::new(); - stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result); - seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?; - buf.clear(); - serialized_result.clear(); - encode::write_postings_to_string(&self.inverted_function_output_index, &mut buf); - stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result); - seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?; - if self.search_unbox { - seq.serialize_element(&1)?; - } - seq.end() - } else { - None::<()>.serialize(serializer) + let mut seq = serializer.serialize_seq(None)?; + let mut buf = Vec::new(); + encode::write_postings_to_string(&self.inverted_function_inputs_index, &mut buf); + let mut serialized_result = Vec::new(); + stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result); + seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?; + buf.clear(); + serialized_result.clear(); + encode::write_postings_to_string(&self.inverted_function_output_index, &mut buf); + stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result); + seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?; + if self.search_unbox { + seq.serialize_element(&1)?; } + seq.end() } } diff --git a/src/tools/clippy/tests/ui/bool_assert_comparison.stderr b/src/tools/clippy/tests/ui/bool_assert_comparison.stderr index f823f08f31dca..72aa6303a2026 100644 --- a/src/tools/clippy/tests/ui/bool_assert_comparison.stderr +++ b/src/tools/clippy/tests/ui/bool_assert_comparison.stderr @@ -272,10 +272,8 @@ LL | assert_eq!(a!(), true); | help: replace it with `assert!(..)` | -LL | true -... -LL | -LL ~ assert!(a!()); +LL - assert_eq!(a!(), true); +LL + assert!(a!()); | error: used `assert_eq!` with a literal bool @@ -286,10 +284,8 @@ LL | assert_eq!(true, b!()); | help: replace it with `assert!(..)` | -LL | true -... -LL | -LL ~ assert!(b!()); +LL - assert_eq!(true, b!()); +LL + assert!(b!()); | error: used `debug_assert_eq!` with a literal bool diff --git a/tests/crashes/131762.rs b/tests/crashes/131762.rs index 85cb9c8f20a8b..4080272226d94 100644 --- a/tests/crashes/131762.rs +++ b/tests/crashes/131762.rs @@ -1,3 +1,4 @@ +//@ needs-rustc-debug-assertions //@ known-bug: #131762 // ignore-tidy-linelength diff --git a/tests/run-make/alloc-no-oom-handling/rmake.rs b/tests/run-make/alloc-no-oom-handling/rmake.rs index 89a6636d9a0cc..94002eca5736f 100644 --- a/tests/run-make/alloc-no-oom-handling/rmake.rs +++ b/tests/run-make/alloc-no-oom-handling/rmake.rs @@ -6,7 +6,7 @@ use run_make_support::{rustc, source_root}; fn main() { rustc() - .edition("2021") + .edition("2024") .arg("-Dwarnings") .crate_type("rlib") .input(source_root().join("library/alloc/src/lib.rs")) diff --git a/tests/run-make/alloc-no-rc/rmake.rs b/tests/run-make/alloc-no-rc/rmake.rs index 12171c2148f1d..8d8cd4990bc65 100644 --- a/tests/run-make/alloc-no-rc/rmake.rs +++ b/tests/run-make/alloc-no-rc/rmake.rs @@ -6,7 +6,7 @@ use run_make_support::{rustc, source_root}; fn main() { rustc() - .edition("2021") + .edition("2024") .arg("-Dwarnings") .crate_type("rlib") .input(source_root().join("library/alloc/src/lib.rs")) diff --git a/tests/run-make/alloc-no-sync/rmake.rs b/tests/run-make/alloc-no-sync/rmake.rs index 29f204f30673e..a096d3941d466 100644 --- a/tests/run-make/alloc-no-sync/rmake.rs +++ b/tests/run-make/alloc-no-sync/rmake.rs @@ -6,7 +6,7 @@ use run_make_support::{rustc, source_root}; fn main() { rustc() - .edition("2021") + .edition("2024") .arg("-Dwarnings") .crate_type("rlib") .input(source_root().join("library/alloc/src/lib.rs")) diff --git a/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs b/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs index d28c8463016cb..00ae400f71d20 100644 --- a/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs +++ b/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs @@ -49,21 +49,21 @@ fn main() { rustc() .input("proc.rs") .crate_type("proc-macro") - .edition("2021") + .edition("2024") .arg("-Cdebuginfo=line-tables-only") .run(); rustc() .extern_("proc", dynamic_lib_name("proc")) .input("other.rs") .crate_type("rlib") - .edition("2021") + .edition("2024") .opt_level("3") .arg("-Cdebuginfo=line-tables-only") .run(); rustc() .extern_("other", rust_lib_name("other")) .input("main.rs") - .edition("2021") + .edition("2024") .opt_level("3") .arg("-Cdebuginfo=line-tables-only") .arg("-Clto=fat") diff --git a/tests/run-make/panic-abort-eh_frame/rmake.rs b/tests/run-make/panic-abort-eh_frame/rmake.rs index 2eccde627955c..5c859a7482674 100644 --- a/tests/run-make/panic-abort-eh_frame/rmake.rs +++ b/tests/run-make/panic-abort-eh_frame/rmake.rs @@ -19,7 +19,7 @@ fn main() { .crate_type("lib") .emit("obj=foo.o") .panic("abort") - .edition("2021") + .edition("2024") .arg("-Zvalidate-mir") .arg("-Cforce-unwind-tables=no") .run(); diff --git a/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs b/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs index 546a0685b4ee5..4f85bf6bef8f9 100644 --- a/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs @@ -19,14 +19,14 @@ fn main() { rustc() .input("src/proc.rs") .crate_name(proc_crate_name) - .edition("2021") + .edition("2024") .crate_type("proc-macro") .emit("dep-info,link") .run(); rustc() .input("src/lib.rs") .crate_name(crate_name) - .edition("2021") + .edition("2024") .crate_type("lib") .emit("dep-info,link") .run(); diff --git a/tests/rustdoc-js/auxiliary/emptytype.rs b/tests/rustdoc-js/auxiliary/emptytype.rs new file mode 100644 index 0000000000000..2a06b4ec9f8ca --- /dev/null +++ b/tests/rustdoc-js/auxiliary/emptytype.rs @@ -0,0 +1,41 @@ +// https://github.com/rust-lang/rust/issues/148431 + +// This test is designed to hit a case where, thanks to the +// recursion limit, the where clause gets generated, but not +// used, because we run out of fuel. +// +// This results in a reverse index with nothing in it, which +// used to crash when we parsed it. +pub fn foobar1, B: T2, C: T3, D: T4>(a: A) {} + +pub trait T1 {} +pub trait T2 {} +pub trait T3 {} +pub trait T4 {} + +// foobar1 is the version that worked at the time this test was written +// the rest are here to try to make the test at least a little more +// robust, in the sense that it actually tests the code and isn't magically +// fixed by the recursion limit changing +pub fn foobar2, B: U2, C: U3, D: U4, E: U5>(a: A) {} + +pub trait U1 {} +pub trait U2 {} +pub trait U3 {} +pub trait U4 {} +pub trait U5 {} + +pub fn foobar3, B: V2, C: V3, D: V4, E: V5, F: V6>(a: A) {} + +pub trait V1 {} +pub trait V2 {} +pub trait V3 {} +pub trait V4 {} +pub trait V5 {} +pub trait V6 {} + +pub fn foobar4, B: W2, C: W3>(a: A) {} + +pub trait W1 {} +pub trait W2 {} +pub trait W3 {} diff --git a/tests/rustdoc-js/empty-type.js b/tests/rustdoc-js/empty-type.js new file mode 100644 index 0000000000000..e4c8f9954cb7f --- /dev/null +++ b/tests/rustdoc-js/empty-type.js @@ -0,0 +1,8 @@ +const EXPECTED = [ + { + query: 'baz', + others: [ + { name: 'baz' } + ], + }, +]; diff --git a/tests/rustdoc-js/empty-type.rs b/tests/rustdoc-js/empty-type.rs new file mode 100644 index 0000000000000..87ea73709b6bb --- /dev/null +++ b/tests/rustdoc-js/empty-type.rs @@ -0,0 +1,8 @@ +//@ aux-crate:emptytype=emptytype.rs +//@ compile-flags: --extern emptytype +//@ aux-build:emptytype.rs +//@ build-aux-docs + +extern crate emptytype; + +pub fn baz() {} diff --git a/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout b/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout index 65989a8ef47c7..1048db07ae95a 100644 --- a/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout +++ b/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout @@ -19,6 +19,7 @@ LL | println!(); error: macro expansion ignores `{` and any tokens following --> $SRC_DIR/std/src/macros.rs:LL:COL | + | ::: $DIR/main-alongside-macro-calls.rs:30:1 | LL | println!(); @@ -41,6 +42,7 @@ LL | println!(); error: macro expansion ignores `{` and any tokens following --> $SRC_DIR/std/src/macros.rs:LL:COL | + | ::: $DIR/main-alongside-macro-calls.rs:34:1 | LL | println!(); diff --git a/tests/rustdoc/macro/auxiliary/one-line-expand.rs b/tests/rustdoc/macro/auxiliary/one-line-expand.rs new file mode 100644 index 0000000000000..14df0f2d4f20e --- /dev/null +++ b/tests/rustdoc/macro/auxiliary/one-line-expand.rs @@ -0,0 +1,15 @@ +//@ force-host +//@ no-prefer-dynamic +//@ compile-flags: --crate-type proc-macro + +#![crate_type = "proc-macro"] +#![crate_name = "just_some_proc"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn repro(_args: TokenStream, _input: TokenStream) -> TokenStream { + "struct Repro;".parse().unwrap() +} diff --git a/tests/rustdoc/macro/one-line-expand.rs b/tests/rustdoc/macro/one-line-expand.rs new file mode 100644 index 0000000000000..ceb9521820d61 --- /dev/null +++ b/tests/rustdoc/macro/one-line-expand.rs @@ -0,0 +1,19 @@ +// Regression test for . +// It ensures that the macro expansion correctly handles its "class stack". + +//@ compile-flags: -Zunstable-options --generate-macro-expansion +//@ aux-build:one-line-expand.rs + +#![crate_name = "foo"] + +extern crate just_some_proc; + +//@ has 'src/foo/one-line-expand.rs.html' +//@ has - '//*[@class="comment"]' '//' +//@ has - '//*[@class="original"]' '#[just_some_proc::repro]' +//@ has - '//*[@class="original"]/*[@class="attr"]' '#[just_some_proc::repro]' +//@ has - '//code/*[@class="kw"]' 'struct ' + +// +#[just_some_proc::repro] +struct Repro; diff --git a/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.rs b/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.rs new file mode 100644 index 0000000000000..f5926e19a150a --- /dev/null +++ b/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.rs @@ -0,0 +1,12 @@ +//@ edition: 2024 + +struct T<'g>(); +//~^ ERROR lifetime parameter `'g` is never used + +fn ord() -> _ { + //~^ WARN type parameter `a` should have an upper camel case name + //~| ERROR the placeholder `_` is not allowed within types on item signatures for return types + async || {} +} + +fn main() {} diff --git a/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.stderr b/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.stderr new file mode 100644 index 0000000000000..ca98d210579f3 --- /dev/null +++ b/tests/ui/async-await/async-closures/ice-async-closure-variance-issue-148488.stderr @@ -0,0 +1,26 @@ +warning: type parameter `a` should have an upper camel case name + --> $DIR/ice-async-closure-variance-issue-148488.rs:6:8 + | +LL | fn ord() -> _ { + | ^ help: convert the identifier to upper camel case: `A` + | + = note: `#[warn(non_camel_case_types)]` (part of `#[warn(nonstandard_style)]`) on by default + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/ice-async-closure-variance-issue-148488.rs:6:16 + | +LL | fn ord() -> _ { + | ^ not allowed in type signatures + +error[E0392]: lifetime parameter `'g` is never used + --> $DIR/ice-async-closure-variance-issue-148488.rs:3:10 + | +LL | struct T<'g>(); + | ^^ unused lifetime parameter + | + = help: consider removing `'g`, referring to it in a field, or using a marker such as `PhantomData` + +error: aborting due to 2 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0121, E0392. +For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr index fe1ecfbe71d4c..66d5a808d03c9 100644 --- a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr +++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr @@ -1,11 +1,11 @@ error[E0369]: cannot add `&str` to `&str` --> $DIR/non-1-width-unicode-multiline-label.rs:8:237 | -LL | ...๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ"; let _a = unicode_is_fun + " really fun!"; - | -------------- ^ -------------- &str - | | | - | | `+` cannot be used to concatenate two `&str` strings - | &str +LL | ... ๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ"; let _a = unicode_is_fun + " really fun!"; + | -------------- ^ -------------- &str + | | | + | | `+` cannot be used to concatenate two `&str` strings + | &str | = note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference @@ -16,11 +16,11 @@ LL | let _ = "๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง error[E0369]: cannot add `&str` to `&str` --> $DIR/non-1-width-unicode-multiline-label.rs:10:384 | -LL | ...๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ"; let _a = unicode_is_fun + " really fun!"; - | -------------- ^ -------------- &str - | | | - | | `+` cannot be used to concatenate two `&str` strings - | &str +LL | ... ๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ"; let _a = unicode_is_fun + " really fun!"; + | -------------- ^ -------------- &str + | | | + | | `+` cannot be used to concatenate two `&str` strings + | &str | = note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference @@ -31,11 +31,11 @@ LL | let _ = "๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง error[E0369]: cannot add `&str` to `&str` --> $DIR/non-1-width-unicode-multiline-label.rs:12:260 | -LL | ...เฟ‡เฟˆเฟ‰เฟŠเฟ‹เฟŒเฟเฟŽเฟเฟเฟ‘เฟ’เฟ“เฟ”เฟ•เฟ–เฟ—เฟ˜เฟ™เฟš"; let _a = unicode_is_fun + " really fun!"; - | -------------- ^ -------------- &str - | | | - | | `+` cannot be used to concatenate two `&str` strings - | &str +LL | ...เฟ†เฟ‡เฟˆเฟ‰เฟŠเฟ‹เฟŒเฟเฟŽเฟเฟเฟ‘เฟ’เฟ“เฟ”เฟ•เฟ–เฟ—เฟ˜เฟ™เฟš"; let _a = unicode_is_fun + " really fun!"; + | -------------- ^ -------------- &str + | | | + | | `+` cannot be used to concatenate two `&str` strings + | &str | = note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr index 4dff15642aeb4..6220a6ba7b310 100644 --- a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr +++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr @@ -1,11 +1,11 @@ error[E0369]: cannot add `&str` to `&str` โ•ญโ–ธ $DIR/non-1-width-unicode-multiline-label.rs:8:237 โ”‚ -LL โ”‚ โ€ฆ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ"; let _a = unicode_is_fun + " really fun!"; - โ”‚ โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”ฏ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ &str - โ”‚ โ”‚ โ”‚ - โ”‚ โ”‚ `+` cannot be used to concatenate two `&str` strings - โ”‚ &str +LL โ”‚ โ€ฆ ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ"; let _a = unicode_is_fun + " really fun!"; + โ”‚ โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”ฏ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ &str + โ”‚ โ”‚ โ”‚ + โ”‚ โ”‚ `+` cannot be used to concatenate two `&str` strings + โ”‚ &str โ”‚ โ•ฐ note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference @@ -16,11 +16,11 @@ LL โ”‚ let _ = "๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง error[E0369]: cannot add `&str` to `&str` โ•ญโ–ธ $DIR/non-1-width-unicode-multiline-label.rs:10:384 โ”‚ -LL โ”‚ โ€ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ"; let _a = unicode_is_fun + " really fun!"; - โ”‚ โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”ฏ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ &str - โ”‚ โ”‚ โ”‚ - โ”‚ โ”‚ `+` cannot be used to concatenate two `&str` strings - โ”‚ &str +LL โ”‚ โ€ฆ ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ"; let _a = unicode_is_fun + " really fun!"; + โ”‚ โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”ฏ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ &str + โ”‚ โ”‚ โ”‚ + โ”‚ โ”‚ `+` cannot be used to concatenate two `&str` strings + โ”‚ &str โ”‚ โ•ฐ note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference @@ -31,11 +31,11 @@ LL โ”‚ let _ = "๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ฆ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง error[E0369]: cannot add `&str` to `&str` โ•ญโ–ธ $DIR/non-1-width-unicode-multiline-label.rs:12:260 โ”‚ -LL โ”‚ โ€ฆเฟ…เฟ†เฟ‡เฟˆเฟ‰เฟŠเฟ‹เฟŒเฟเฟŽเฟเฟเฟ‘เฟ’เฟ“เฟ”เฟ•เฟ–เฟ—เฟ˜เฟ™เฟš"; let _a = unicode_is_fun + " really fun!"; - โ”‚ โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”ฏ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ &str - โ”‚ โ”‚ โ”‚ - โ”‚ โ”‚ `+` cannot be used to concatenate two `&str` strings - โ”‚ &str +LL โ”‚ โ€ฆเฟ„เฟ…เฟ†เฟ‡เฟˆเฟ‰เฟŠเฟ‹เฟŒเฟเฟŽเฟเฟเฟ‘เฟ’เฟ“เฟ”เฟ•เฟ–เฟ—เฟ˜เฟ™เฟš"; let _a = unicode_is_fun + " really fun!"; + โ”‚ โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”ฏ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ &str + โ”‚ โ”‚ โ”‚ + โ”‚ โ”‚ `+` cannot be used to concatenate two `&str` strings + โ”‚ &str โ”‚ โ•ฐ note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference diff --git a/tests/ui/diagnostic-width/non-whitespace-trimming-unicode.stderr b/tests/ui/diagnostic-width/non-whitespace-trimming-unicode.stderr index e74afbfeac478..46369c551cf38 100644 --- a/tests/ui/diagnostic-width/non-whitespace-trimming-unicode.stderr +++ b/tests/ui/diagnostic-width/non-whitespace-trimming-unicode.stderr @@ -1,10 +1,10 @@ error[E0308]: mismatched types --> $DIR/non-whitespace-trimming-unicode.rs:5:415 | -LL | ...โ™ฃโ™คโ™ฅโ™ฆโ™งโ™จโ™ฉโ™ชโ™ซโ™ฌโ™ญโ™ฎโ™ฏโ™ฐโ™ฑโ™ฒโ™ณโ™ดโ™ตโ™ถโ™ทโ™ธโ™นโ™บโ™ปโ™ผโ™ฝโ™พโ™ฟโš€โšโš‚โšƒโš„โš…โš†โšˆโš‰4"; let _: () = 42; let _: &str = "๐Ÿฆ€โ˜€โ˜โ˜‚โ˜ƒโ˜„โ˜…โ˜†โ˜‡โ˜ˆโ˜‰โ˜Šโ˜‹โ˜Œโ˜โ˜Žโ˜โ˜โ˜‘โ˜’โ˜“ โ˜–โ˜—โ˜˜โ˜™โ˜šโ˜›โ˜œโ˜โ˜žโ˜Ÿโ˜ โ˜กโ˜ขโ˜ฃโ˜คโ˜ฅโ˜ฆโ˜งโ˜จโ˜ฉโ˜ชโ˜ซโ˜ฌโ˜ญโ˜ฎโ˜ฏโ˜ฐโ˜ฑโ˜ฒโ˜ณโ˜ดโ˜ตโ˜ถโ˜ทโ˜ธโ˜นโ˜บโ˜ปโ˜ผโ˜ฝ ... - | -- ^^ expected `()`, found integer - | | - | expected due to this +LL | ...โ™คโ™ฅโ™ฆโ™งโ™จโ™ฉโ™ชโ™ซโ™ฌโ™ญโ™ฎโ™ฏโ™ฐโ™ฑโ™ฒโ™ณโ™ดโ™ตโ™ถโ™ทโ™ธโ™นโ™บโ™ปโ™ผโ™ฝโ™พโ™ฟโš€โšโš‚โšƒโš„โš…โš†โšˆโš‰4"; let _: () = 42; let _: &str = "๐Ÿฆ€โ˜€โ˜โ˜‚โ˜ƒโ˜„โ˜…โ˜†โ˜‡โ˜ˆโ˜‰โ˜Šโ˜‹โ˜Œโ˜โ˜Žโ˜โ˜โ˜‘โ˜’โ˜“ โ˜–โ˜—โ˜˜โ˜™โ˜šโ˜›โ˜œโ˜โ˜žโ˜Ÿโ˜ โ˜กโ˜ขโ˜ฃโ˜คโ˜ฅโ˜ฆโ˜งโ˜จโ˜ฉโ˜ชโ˜ซโ˜ฌโ˜ญโ˜ฎโ˜ฏโ˜ฐโ˜ฑโ˜ฒโ˜ณ... + | -- ^^ expected `()`, found integer + | | + | expected due to this error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/tabs-trimming.stderr b/tests/ui/diagnostic-width/tabs-trimming.stderr index e0d1c2d95a965..dfda30e6005b0 100644 --- a/tests/ui/diagnostic-width/tabs-trimming.stderr +++ b/tests/ui/diagnostic-width/tabs-trimming.stderr @@ -1,20 +1,20 @@ error[E0408]: variable `v` is not bound in all patterns --> $DIR/tabs-trimming.rs:9:16 | -LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... - | - ^ ^ pattern doesn't bind `v` - | | | - | | pattern doesn't bind `v` - | variable not in all patterns +LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... + | - ^ ^ pattern doesn't bind `v` + | | | + | | pattern doesn't bind `v` + | variable not in all patterns error[E0381]: used binding `v` is possibly-uninitialized --> $DIR/tabs-trimming.rs:9:67 | -LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... - | - ^ `v` used here but it is possibly-uninitialized - | | - | binding initialized here in some conditions - | binding declared here but left uninitialized +LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... + | - ^ `v` used here but it is possibly-uninitialized + | | + | binding initialized here in some conditions + | binding declared here but left uninitialized error: aborting due to 2 previous errors diff --git a/tests/ui/error-emitter/unicode-output.svg b/tests/ui/error-emitter/unicode-output.svg index 9c1b7c80f4331..5623421ab7886 100644 --- a/tests/ui/error-emitter/unicode-output.svg +++ b/tests/ui/error-emitter/unicode-output.svg @@ -55,7 +55,7 @@ LL โ”‚ โ”‚ )>>) {} - โ•ฐโ•ดโ””โ”€โ”€โ”€โ”˜ + โ•ฐโ•ดโ””โ”€โ”€โ”€โ”˜ diff --git a/tests/ui/include-macros/mismatched-types.stderr b/tests/ui/include-macros/mismatched-types.stderr index 8d541966a6a40..4fab832c2d8e8 100644 --- a/tests/ui/include-macros/mismatched-types.stderr +++ b/tests/ui/include-macros/mismatched-types.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/file.txt:0:1 | +LL | + | ^ expected `&[u8]`, found `&str` | ::: $DIR/mismatched-types.rs:2:12 | diff --git a/tests/ui/macros/same-sequence-span.stderr b/tests/ui/macros/same-sequence-span.stderr index 1ca89b6b595c8..d6652453e9a9e 100644 --- a/tests/ui/macros/same-sequence-span.stderr +++ b/tests/ui/macros/same-sequence-span.stderr @@ -17,14 +17,8 @@ LL | $(= $z:tt)* error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments --> $DIR/same-sequence-span.rs:20:1 | -LL | | // `proc_macro_sequence.rs`. - | |_____________________________^not allowed after `expr` fragments -... -LL | proc_macro_sequence::make_foo!(); - | ^------------------------------- - | | - | _in this macro invocation - | | +LL | proc_macro_sequence::make_foo!(); + | -------------------------------- in this macro invocation | = note: allowed there are: `=>`, `,` or `;` = note: this error originates in the macro `proc_macro_sequence::make_foo` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/pattern/const-error-ice-issue-148542.rs b/tests/ui/pattern/const-error-ice-issue-148542.rs new file mode 100644 index 0000000000000..3c3645dc2c018 --- /dev/null +++ b/tests/ui/pattern/const-error-ice-issue-148542.rs @@ -0,0 +1,13 @@ +//@ edition: 2021 + +// Regression test for #148542 +// Ensure we don't ICE with "Invalid `ConstKind` for `const_to_pat`: {const error}" + +fn foo() where &str:, { + //~^ ERROR `&` without an explicit lifetime name cannot be used here + match 42_u8 { + -10.. => {} + } +} + +fn main() {} diff --git a/tests/ui/pattern/const-error-ice-issue-148542.stderr b/tests/ui/pattern/const-error-ice-issue-148542.stderr new file mode 100644 index 0000000000000..ee39ba4feb093 --- /dev/null +++ b/tests/ui/pattern/const-error-ice-issue-148542.stderr @@ -0,0 +1,14 @@ +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/const-error-ice-issue-148542.rs:6:16 + | +LL | fn foo() where &str:, { + | ^ explicit lifetime name needed here + | +help: consider introducing a higher-ranked lifetime here + | +LL | fn foo() where for<'a> &'a str:, { + | +++++++ ++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0637`. diff --git a/tests/ui/statics/check-values-constraints.stderr b/tests/ui/statics/check-values-constraints.stderr index c54f4830533ae..f6fa8df45e5e4 100644 --- a/tests/ui/statics/check-values-constraints.stderr +++ b/tests/ui/statics/check-values-constraints.stderr @@ -38,10 +38,10 @@ LL | field2: SafeEnum::Variant4("str".to_string()), note: method `to_string` is not const because trait `ToString` is not const --> $SRC_DIR/alloc/src/string.rs:LL:COL | - = note: this trait is not const + = note: this method is not const ::: $SRC_DIR/alloc/src/string.rs:LL:COL | - = note: this method is not const + = note: this trait is not const = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` diff --git a/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs b/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs new file mode 100644 index 0000000000000..f8f6ed9a09887 --- /dev/null +++ b/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs @@ -0,0 +1,36 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +// Regression test for trait-system-refactor-initiative#244 + +trait Trait { + type Assoc; +} + +// We have param env candidate for the trait goal but not the projection. +// Under such circumstance, consider object candidate if the self_ty is trait object. +fn foo(x: as Trait>::Assoc) -> T +where + dyn Trait: Trait, +{ + x +} + +trait Id<'a> { + type This: ?Sized; +} +impl Id<'_> for T { + type This = T; +} + +// Ensure that we properly normalize alias self_ty before evaluating the goal. +fn alias_foo(x: for<'a> fn( + < as Id<'a>>::This as Trait>::Assoc +)) -> fn(T) +where + dyn Trait: Trait, +{ + x +} + +fn main() {} diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index 0b70ac97fd435..747d032dfd4be 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -686,11 +686,12 @@ LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | note: method `filter` is not const because trait `Iterator` is not const --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - | - = note: this trait is not const ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL | = note: this method is not const + ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | + = note: this trait is not const = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const method `, {closure@$DIR/typeck_type_placeholder_item.rs:240:29: 240:32}> as Iterator>::map::` in constants @@ -701,11 +702,12 @@ LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | note: method `map` is not const because trait `Iterator` is not const --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - | - = note: this trait is not const ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL | = note: this method is not const + ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | + = note: this trait is not const = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 83 previous errors