diff --git a/Cargo.lock b/Cargo.lock index fb619d3870f3..01445e97ae70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3488,6 +3488,7 @@ dependencies = [ "rustc_trait_selection", "rustc_ty_utils", "serde_json", + "time", "tracing", "windows", ] @@ -5142,6 +5143,33 @@ dependencies = [ name = "tier-check" version = "0.1.0" +[[package]] +name = "time" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +dependencies = [ + "time-core", +] + [[package]] name = "tinystr" version = "0.7.1" diff --git a/RELEASES.md b/RELEASES.md index 3205b02e5c45..e8c79c573f97 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -92,7 +92,6 @@ Cargo ----- - [Allow named debuginfo options in `Cargo.toml`.](https://github.com/rust-lang/cargo/pull/11958/) - [Add `workspace_default_members` to the output of `cargo metadata`.](https://github.com/rust-lang/cargo/pull/11978/) -- [`cargo add` now considers `rust-version` when selecting packages.](https://github.com/rust-lang/cargo/pull/12078/) - [Automatically inherit workspace fields when running `cargo new`/`cargo init`.](https://github.com/rust-lang/cargo/pull/12069/) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 429e62c4a1c6..9e193402feb2 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1619,13 +1619,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { debug!(?hir_bounds); let lifetime_mapping = if in_trait { - self.arena.alloc_from_iter( - collected_lifetime_mapping - .iter() - .map(|(lifetime, def_id)| (**lifetime, *def_id)), + Some( + &*self.arena.alloc_from_iter( + collected_lifetime_mapping + .iter() + .map(|(lifetime, def_id)| (**lifetime, *def_id)), + ), ) } else { - &mut [] + None }; let opaque_ty_item = hir::OpaqueTy { @@ -2090,13 +2092,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { debug!("lower_async_fn_ret_ty: generic_params={:#?}", generic_params); let lifetime_mapping = if in_trait { - self.arena.alloc_from_iter( - collected_lifetime_mapping - .iter() - .map(|(lifetime, def_id)| (**lifetime, *def_id)), + Some( + &*self.arena.alloc_from_iter( + collected_lifetime_mapping + .iter() + .map(|(lifetime, def_id)| (**lifetime, *def_id)), + ), ) } else { - &mut [] + None }; let opaque_ty_item = hir::OpaqueTy { diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 278e450c6b51..97c3e0b879a6 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -695,7 +695,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .find_map(find_fn_kind_from_did), ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => tcx .explicit_item_bounds(def_id) - .arg_iter_copied(tcx, args) + .iter_instantiated_copied(tcx, args) .find_map(|(clause, span)| find_fn_kind_from_did((clause, span))), ty::Closure(_, args) => match args.as_closure().kind() { ty::ClosureKind::Fn => Some(hir::Mutability::Not), diff --git a/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs b/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs index b8f901d1ba17..80a2776ca1e2 100644 --- a/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs +++ b/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs @@ -22,7 +22,7 @@ fn main() { #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] let nan = f32::NAN; - // MIPS hardware treats f32::NAN as SNAN. Clear the signaling bit. + // MIPS hardware except MIPS R6 treats f32::NAN as SNAN. Clear the signaling bit. // See https://github.com/rust-lang/rust/issues/52746. #[cfg(any(target_arch = "mips", target_arch = "mips64"))] let nan = f32::from_bits(f32::NAN.to_bits() - 1); diff --git a/compiler/rustc_codegen_gcc/example/alloc_system.rs b/compiler/rustc_codegen_gcc/example/alloc_system.rs index 046903fe5aca..e756b347e89e 100644 --- a/compiler/rustc_codegen_gcc/example/alloc_system.rs +++ b/compiler/rustc_codegen_gcc/example/alloc_system.rs @@ -10,6 +10,7 @@ #[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "mips", + target_arch = "mips32r6", target_arch = "powerpc", target_arch = "powerpc64"))] const MIN_ALIGN: usize = 8; @@ -17,6 +18,7 @@ const MIN_ALIGN: usize = 8; target_arch = "aarch64", target_arch = "loongarch64", target_arch = "mips64", + target_arch = "mips64r6", target_arch = "s390x", target_arch = "sparc64"))] const MIN_ALIGN: usize = 16; diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index de1622951fed..aed4a8f3c85f 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -1,7 +1,8 @@ codegen_llvm_copy_bitcode = failed to copy bitcode to object file: {$err} codegen_llvm_dlltool_fail_import_library = - Dlltool could not create import library: {$stdout} + Dlltool could not create import library with {$dlltool_path} {$dlltool_args}: + {$stdout} {$stderr} codegen_llvm_dynamic_linking_with_lto = diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 39275272e422..4c69b9503a2c 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -335,6 +335,10 @@ pub fn from_fn_attrs<'ll, 'tcx>( to_add.extend(probestack_attr(cx)); to_add.extend(stackprotector_attr(cx)); + if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_BUILTINS) { + to_add.push(llvm::CreateAttrString(cx.llcx, "no-builtins")); + } + if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::COLD) { to_add.push(AttributeKind::Cold.create_attr(cx.llcx)); } diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index a6416e9540cc..10bf954d242c 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -198,25 +198,24 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { "arm" => ("arm", "--32"), _ => panic!("unsupported arch {}", sess.target.arch), }; - let result = std::process::Command::new(&dlltool) - .args([ - "-d", - def_file_path.to_str().unwrap(), - "-D", - lib_name, - "-l", - output_path.to_str().unwrap(), - "-m", - dlltool_target_arch, - "-f", - dlltool_target_bitness, - "--no-leading-underscore", - "--temp-prefix", - temp_prefix.to_str().unwrap(), - ]) - .output(); + let mut dlltool_cmd = std::process::Command::new(&dlltool); + dlltool_cmd.args([ + "-d", + def_file_path.to_str().unwrap(), + "-D", + lib_name, + "-l", + output_path.to_str().unwrap(), + "-m", + dlltool_target_arch, + "-f", + dlltool_target_bitness, + "--no-leading-underscore", + "--temp-prefix", + temp_prefix.to_str().unwrap(), + ]); - match result { + match dlltool_cmd.output() { Err(e) => { sess.emit_fatal(ErrorCallingDllTool { dlltool_path: dlltool.to_string_lossy(), @@ -226,6 +225,12 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { // dlltool returns '0' on failure, so check for error output instead. Ok(output) if !output.stderr.is_empty() => { sess.emit_fatal(DlltoolFailImportLibrary { + dlltool_path: dlltool.to_string_lossy(), + dlltool_args: dlltool_cmd + .get_args() + .map(|arg| arg.to_string_lossy()) + .collect::>() + .join(" "), stdout: String::from_utf8_lossy(&output.stdout), stderr: String::from_utf8_lossy(&output.stderr), }) diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 44869ced1ae1..fced6d504d26 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -81,6 +81,8 @@ pub(crate) struct ErrorCallingDllTool<'a> { #[derive(Diagnostic)] #[diag(codegen_llvm_dlltool_fail_import_library)] pub(crate) struct DlltoolFailImportLibrary<'a> { + pub dlltool_path: Cow<'a, str>, + pub dlltool_args: String, pub stdout: Cow<'a, str>, pub stderr: Cow<'a, str>, } diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 1f827a2375df..e8b8665e39d4 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -193,8 +193,8 @@ pub(crate) fn create_object_file(sess: &Session) -> Option Architecture::I386, "s390x" => Architecture::S390x, - "mips" => Architecture::Mips, - "mips64" => Architecture::Mips64, + "mips" | "mips32r6" => Architecture::Mips, + "mips64" | "mips64r6" => Architecture::Mips64, "x86_64" => { if sess.target.pointer_width == 32 { Architecture::X86_64_X32 diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index ececa29b2315..1c5d7a7c68e9 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -362,7 +362,7 @@ pub struct CodegenContext { impl CodegenContext { pub fn create_diag_handler(&self) -> Handler { - Handler::with_emitter(true, None, Box::new(self.diag_emitter.clone())) + Handler::with_emitter(true, None, Box::new(self.diag_emitter.clone()), None) } pub fn config(&self, kind: ModuleKind) -> &ModuleConfig { diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index d6c230127626..0c7b8a796128 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -1,4 +1,4 @@ -use rustc_ast::{ast, MetaItemKind, NestedMetaItem}; +use rustc_ast::{ast, attr, MetaItemKind, NestedMetaItem}; use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_errors::struct_span_err; use rustc_hir as hir; @@ -60,6 +60,14 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER; } + // When `no_builtins` is applied at the crate level, we should add the + // `no-builtins` attribute to each function to ensure it takes effect in LTO. + let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); + let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins); + if no_builtins { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_BUILTINS; + } + let supported_target_features = tcx.supported_target_features(LOCAL_CRATE); let mut inline_span = None; diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 7b5d83c612ad..48c6c75bb1a2 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -321,7 +321,7 @@ pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Opt "aarch64" => AARCH64_ALLOWED_FEATURES, "x86" | "x86_64" => X86_ALLOWED_FEATURES, "hexagon" => HEXAGON_ALLOWED_FEATURES, - "mips" | "mips64" => MIPS_ALLOWED_FEATURES, + "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_ALLOWED_FEATURES, "powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES, "riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES, "wasm32" | "wasm64" => WASM_ALLOWED_FEATURES, diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 67352c55c901..a7b01618ade3 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [lib] [dependencies] +time = { version = "0.3", default-features = false, features = ["formatting", ] } tracing = { version = "0.1.35" } serde_json = "1.0.59" rustc_log = { path = "../rustc_log" } diff --git a/compiler/rustc_driver_impl/messages.ftl b/compiler/rustc_driver_impl/messages.ftl index 22b4ec6b0d1b..9b2f2c338607 100644 --- a/compiler/rustc_driver_impl/messages.ftl +++ b/compiler/rustc_driver_impl/messages.ftl @@ -3,7 +3,11 @@ driver_impl_ice_bug_report = we would appreciate a bug report: {$bug_report_url} driver_impl_ice_exclude_cargo_defaults = some of the compiler flags provided by cargo are hidden driver_impl_ice_flags = compiler flags: {$flags} +driver_impl_ice_path = please attach the file at `{$path}` to your bug report +driver_impl_ice_path_error = the ICE couldn't be written to `{$path}`: {$error} +driver_impl_ice_path_error_env = the environment variable `RUSTC_ICE` is set to `{$env_var}` driver_impl_ice_version = rustc {$version} running on {$triple} + driver_impl_rlink_empty_version_number = The input does not contain version number driver_impl_rlink_encoding_version_mismatch = .rlink file was produced with encoding version `{$version_array}`, but the current version is `{$rlink_version}` diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 25c043149e81..11303e7d09e8 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -7,6 +7,8 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(lazy_cell)] #![feature(decl_macro)] +#![feature(ice_to_disk)] +#![feature(let_chains)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] #![deny(rustc::untranslatable_diagnostic)] @@ -57,8 +59,11 @@ use std::panic::{self, catch_unwind}; use std::path::PathBuf; use std::process::{self, Command, Stdio}; use std::str; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::OnceLock; -use std::time::Instant; +use std::time::{Instant, SystemTime}; +use time::format_description::well_known::Rfc3339; +use time::OffsetDateTime; #[allow(unused_macros)] macro do_not_use_print($($t:tt)*) { @@ -294,6 +299,7 @@ fn run_compiler( input: Input::File(PathBuf::new()), output_file: ofile, output_dir: odir, + ice_file: ice_path().clone(), file_loader, locale_resources: DEFAULT_LOCALE_RESOURCES, lint_caps: Default::default(), @@ -1292,9 +1298,29 @@ pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 { } } -/// Stores the default panic hook, from before [`install_ice_hook`] was called. -static DEFAULT_HOOK: OnceLock) + Sync + Send + 'static>> = - OnceLock::new(); +pub static ICE_PATH: OnceLock> = OnceLock::new(); + +pub fn ice_path() -> &'static Option { + ICE_PATH.get_or_init(|| { + if !rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build() { + return None; + } + if let Ok("0") = std::env::var("RUST_BACKTRACE").as_deref() { + return None; + } + let mut path = match std::env::var("RUSTC_ICE").as_deref() { + // Explicitly opting out of writing ICEs to disk. + Ok("0") => return None, + Ok(s) => PathBuf::from(s), + Err(_) => std::env::current_dir().unwrap_or_default(), + }; + let now: OffsetDateTime = SystemTime::now().into(); + let file_now = now.format(&Rfc3339).unwrap_or(String::new()); + let pid = std::process::id(); + path.push(format!("rustc-ice-{file_now}-{pid}.txt")); + Some(path) + }) +} /// Installs a panic hook that will print the ICE message on unexpected panics. /// @@ -1318,8 +1344,6 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler)) std::env::set_var("RUST_BACKTRACE", "full"); } - let default_hook = DEFAULT_HOOK.get_or_init(panic::take_hook); - panic::set_hook(Box::new(move |info| { // If the error was caused by a broken pipe then this is not a bug. // Write the error and return immediately. See #98700. @@ -1336,7 +1360,7 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler)) // Invoke the default handler, which prints the actual panic message and optionally a backtrace // Don't do this for delayed bugs, which already emit their own more useful backtrace. if !info.payload().is::() { - (*default_hook)(info); + std::panic_hook_with_disk_dump(info, ice_path().as_deref()); // Separate the output with an empty line eprintln!(); @@ -1368,7 +1392,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info: false, TerminalUrl::No, )); - let handler = rustc_errors::Handler::with_emitter(true, None, emitter); + let handler = rustc_errors::Handler::with_emitter(true, None, emitter, None); // a .span_bug or .bug call has already printed what // it wants to print. @@ -1379,10 +1403,40 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info: } handler.emit_note(session_diagnostics::IceBugReport { bug_report_url }); - handler.emit_note(session_diagnostics::IceVersion { - version: util::version_str!().unwrap_or("unknown_version"), - triple: config::host_triple(), - }); + + let version = util::version_str!().unwrap_or("unknown_version"); + let triple = config::host_triple(); + + static FIRST_PANIC: AtomicBool = AtomicBool::new(true); + + let file = if let Some(path) = ice_path().as_ref() { + // Create the ICE dump target file. + match crate::fs::File::options().create(true).append(true).open(&path) { + Ok(mut file) => { + handler + .emit_note(session_diagnostics::IcePath { path: path.display().to_string() }); + if FIRST_PANIC.swap(false, Ordering::SeqCst) { + let _ = write!(file, "\n\nrustc version: {version}\nplatform: {triple}"); + } + Some(file) + } + Err(err) => { + // The path ICE couldn't be written to disk, provide feedback to the user as to why. + handler.emit_warning(session_diagnostics::IcePathError { + path: path.display().to_string(), + error: err.to_string(), + env_var: std::env::var("RUSTC_ICE") + .ok() + .map(|env_var| session_diagnostics::IcePathErrorEnv { env_var }), + }); + handler.emit_note(session_diagnostics::IceVersion { version, triple }); + None + } + } + } else { + handler.emit_note(session_diagnostics::IceVersion { version, triple }); + None + }; if let Some((flags, excluded_cargo_defaults)) = extra_compiler_flags() { handler.emit_note(session_diagnostics::IceFlags { flags: flags.join(" ") }); @@ -1396,7 +1450,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info: let num_frames = if backtrace { None } else { Some(2) }; - interface::try_print_query_stack(&handler, num_frames); + interface::try_print_query_stack(&handler, num_frames, file); // We don't trust this callback not to panic itself, so run it at the end after we're sure we've // printed all the relevant info. diff --git a/compiler/rustc_driver_impl/src/session_diagnostics.rs b/compiler/rustc_driver_impl/src/session_diagnostics.rs index 638b368f7021..f7f06b7d0f2b 100644 --- a/compiler/rustc_driver_impl/src/session_diagnostics.rs +++ b/compiler/rustc_driver_impl/src/session_diagnostics.rs @@ -1,4 +1,4 @@ -use rustc_macros::Diagnostic; +use rustc_macros::{Diagnostic, Subdiagnostic}; #[derive(Diagnostic)] #[diag(driver_impl_rlink_unable_to_read)] @@ -56,6 +56,27 @@ pub(crate) struct IceVersion<'a> { pub triple: &'a str, } +#[derive(Diagnostic)] +#[diag(driver_impl_ice_path)] +pub(crate) struct IcePath { + pub path: String, +} + +#[derive(Diagnostic)] +#[diag(driver_impl_ice_path_error)] +pub(crate) struct IcePathError { + pub path: String, + pub error: String, + #[subdiagnostic] + pub env_var: Option, +} + +#[derive(Subdiagnostic)] +#[note(driver_impl_ice_path_error_env)] +pub(crate) struct IcePathErrorEnv { + pub env_var: String, +} + #[derive(Diagnostic)] #[diag(driver_impl_ice_flags)] pub(crate) struct IceFlags { diff --git a/compiler/rustc_error_codes/src/error_codes/E0391.md b/compiler/rustc_error_codes/src/error_codes/E0391.md index dff50ccaa0b7..457fbd002a14 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0391.md +++ b/compiler/rustc_error_codes/src/error_codes/E0391.md @@ -14,3 +14,6 @@ trait SecondTrait : FirstTrait { The previous example contains a circular dependency between two traits: `FirstTrait` depends on `SecondTrait` which itself depends on `FirstTrait`. + +See https://rustc-dev-guide.rust-lang.org/overview.html#queries and +https://rustc-dev-guide.rust-lang.org/query.html for more information. diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 51e1fe531dd1..1879ece59e32 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -354,6 +354,13 @@ impl DiagnosticMessage { } } } + + pub fn as_str(&self) -> Option<&str> { + match self { + DiagnosticMessage::Eager(s) | DiagnosticMessage::Str(s) => Some(s), + DiagnosticMessage::FluentIdentifier(_, _) => None, + } + } } impl From for DiagnosticMessage { diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 9d4d159fd964..a0fa4115c3e4 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -1982,7 +1982,7 @@ impl EmitterWriter { // We special case `#[derive(_)]\n` and other attribute suggestions, because those // are the ones where context is most useful. let file_lines = sm - .span_to_lines(span.primary_span().unwrap().shrink_to_hi()) + .span_to_lines(parts[0].span.shrink_to_hi()) .expect("span_to_lines failed when emitting suggestion"); let line_num = sm.lookup_char_pos(parts[0].span.lo()).line; if let Some(line) = file_lines.file.get_line(line_num - 1) { diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index 671dc449eaa7..db0dd4ffe8e1 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -64,7 +64,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { ); let span = Span::with_root_ctxt(BytePos(span.0), BytePos(span.1)); - let handler = Handler::with_emitter(true, None, Box::new(je)); + let handler = Handler::with_emitter(true, None, Box::new(je), None); handler.span_err(span, "foo"); let bytes = output.lock().unwrap(); diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index b9db25103a3a..1da02e1bb012 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -47,9 +47,10 @@ use std::borrow::Cow; use std::error::Report; use std::fmt; use std::hash::Hash; +use std::io::Write; use std::num::NonZeroUsize; use std::panic; -use std::path::Path; +use std::path::{Path, PathBuf}; use termcolor::{Color, ColorSpec}; @@ -461,6 +462,10 @@ struct HandlerInner { /// /// [RFC-2383]: https://rust-lang.github.io/rfcs/2383-lint-reasons.html fulfilled_expectations: FxHashSet, + + /// The file where the ICE information is stored. This allows delayed_span_bug backtraces to be + /// stored along side the main panic backtrace. + ice_file: Option, } /// A key denoting where from a diagnostic was stashed. @@ -550,6 +555,7 @@ impl Handler { sm: Option>, fluent_bundle: Option>, fallback_bundle: LazyFallbackBundle, + ice_file: Option, ) -> Self { Self::with_tty_emitter_and_flags( color_config, @@ -557,6 +563,7 @@ impl Handler { fluent_bundle, fallback_bundle, HandlerFlags { can_emit_warnings, treat_err_as_bug, ..Default::default() }, + ice_file, ) } @@ -566,6 +573,7 @@ impl Handler { fluent_bundle: Option>, fallback_bundle: LazyFallbackBundle, flags: HandlerFlags, + ice_file: Option, ) -> Self { let emitter = Box::new(EmitterWriter::stderr( color_config, @@ -579,23 +587,26 @@ impl Handler { flags.track_diagnostics, TerminalUrl::No, )); - Self::with_emitter_and_flags(emitter, flags) + Self::with_emitter_and_flags(emitter, flags, ice_file) } pub fn with_emitter( can_emit_warnings: bool, treat_err_as_bug: Option, emitter: Box, + ice_file: Option, ) -> Self { Handler::with_emitter_and_flags( emitter, HandlerFlags { can_emit_warnings, treat_err_as_bug, ..Default::default() }, + ice_file, ) } pub fn with_emitter_and_flags( emitter: Box, flags: HandlerFlags, + ice_file: Option, ) -> Self { Self { flags, @@ -618,6 +629,7 @@ impl Handler { check_unstable_expect_diagnostics: false, unstable_expect_diagnostics: Vec::new(), fulfilled_expectations: Default::default(), + ice_file, }), } } @@ -991,7 +1003,7 @@ impl Handler { self.emit_diag_at_span(Diagnostic::new_with_code(Warning(None), Some(code), msg), span); } - pub fn span_bug(&self, span: impl Into, msg: impl Into) -> ! { + pub fn span_bug(&self, span: impl Into, msg: impl Into) -> ! { self.inner.borrow_mut().span_bug(span, msg) } @@ -1000,7 +1012,7 @@ impl Handler { pub fn delay_span_bug( &self, span: impl Into, - msg: impl Into, + msg: impl Into, ) -> ErrorGuaranteed { self.inner.borrow_mut().delay_span_bug(span, msg) } @@ -1584,8 +1596,8 @@ impl HandlerInner { } #[track_caller] - fn span_bug(&mut self, sp: impl Into, msg: impl Into) -> ! { - self.emit_diag_at_span(Diagnostic::new(Bug, msg), sp); + fn span_bug(&mut self, sp: impl Into, msg: impl Into) -> ! { + self.emit_diag_at_span(Diagnostic::new(Bug, msg.into()), sp); panic::panic_any(ExplicitBug); } @@ -1598,7 +1610,7 @@ impl HandlerInner { fn delay_span_bug( &mut self, sp: impl Into, - msg: impl Into, + msg: impl Into, ) -> ErrorGuaranteed { // This is technically `self.treat_err_as_bug()` but `delay_span_bug` is called before // incrementing `err_count` by one, so we need to +1 the comparing. @@ -1607,9 +1619,9 @@ impl HandlerInner { self.err_count() + self.lint_err_count + self.delayed_bug_count() + 1 >= c.get() }) { // FIXME: don't abort here if report_delayed_bugs is off - self.span_bug(sp, msg); + self.span_bug(sp, msg.into()); } - let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg); + let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg.into()); diagnostic.set_span(sp.into()); self.emit_diagnostic(&mut diagnostic).unwrap() } @@ -1657,8 +1669,21 @@ impl HandlerInner { explanation: impl Into + Copy, ) { let mut no_bugs = true; + // If backtraces are enabled, also print the query stack + let backtrace = std::env::var_os("RUST_BACKTRACE").map_or(true, |x| &x != "0"); for bug in bugs { - let mut bug = bug.decorate(); + if let Some(file) = self.ice_file.as_ref() + && let Ok(mut out) = std::fs::File::options().append(true).open(file) + { + let _ = write!( + &mut out, + "\n\ndelayed span bug: {}\n{}", + bug.inner.styled_message().iter().filter_map(|(msg, _)| msg.as_str()).collect::(), + &bug.note + ); + } + let mut bug = + if backtrace || self.ice_file.is_none() { bug.decorate() } else { bug.inner }; if no_bugs { // Put the overall explanation before the `DelayedBug`s, to diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 4b0907cf15a6..12473a2bb0bd 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1147,7 +1147,7 @@ impl<'a> ExtCtxt<'a> { pub fn span_warn>(&self, sp: S, msg: impl Into) { self.sess.parse_sess.span_diagnostic.span_warn(sp, msg); } - pub fn span_bug>(&self, sp: S, msg: impl Into) -> ! { + pub fn span_bug>(&self, sp: S, msg: impl Into) -> ! { self.sess.parse_sess.span_diagnostic.span_bug(sp, msg); } pub fn trace_macros_diag(&mut self) { diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 42cc0a6b143c..102bae2a7449 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -1200,7 +1200,7 @@ fn check_matcher_core<'tt>( err.span_label(sp, format!("not allowed after `{}` fragments", kind)); if kind == NonterminalKind::PatWithOr - && sess.edition.rust_2021() + && sess.edition.at_least_rust_2021() && next_token.is_token(&BinOp(token::BinOpToken::Or)) { let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl( diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs index 8a5e09475ff1..6490e52955db 100644 --- a/compiler/rustc_expand/src/tests.rs +++ b/compiler/rustc_expand/src/tests.rs @@ -161,7 +161,7 @@ fn test_harness(file_text: &str, span_labels: Vec, expected_output: & false, TerminalUrl::No, ); - let handler = Handler::with_emitter(true, None, Box::new(emitter)); + let handler = Handler::with_emitter(true, None, Box::new(emitter), None); #[allow(rustc::untranslatable_diagnostic)] handler.span_err(msp, "foo"); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 35ef30114b71..68f1559ea220 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2664,10 +2664,19 @@ pub struct OpaqueTy<'hir> { pub generics: &'hir Generics<'hir>, pub bounds: GenericBounds<'hir>, pub origin: OpaqueTyOrigin, - // Opaques have duplicated lifetimes, this mapping connects the original lifetime with the copy - // so we can later generate bidirectional outlives predicates to enforce that these lifetimes - // stay in sync. - pub lifetime_mapping: &'hir [(Lifetime, LocalDefId)], + /// Return-position impl traits (and async futures) must "reify" any late-bound + /// lifetimes that are captured from the function signature they originate from. + /// + /// This is done by generating a new early-bound lifetime parameter local to the + /// opaque which is substituted in the function signature with the late-bound + /// lifetime. + /// + /// This mapping associated a captured lifetime (first parameter) with the new + /// early-bound lifetime that was generated for the opaque. + pub lifetime_mapping: Option<&'hir [(Lifetime, LocalDefId)]>, + /// Whether the opaque is a return-position impl trait (or async future) + /// originating from a trait method. This makes it so that the opaque is + /// lowered as an associated type. pub in_trait: bool, } diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs index 05a3ab63d5cf..ff55174f97a7 100644 --- a/compiler/rustc_hir_analysis/src/astconv/lint.rs +++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs @@ -86,7 +86,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { )); } - if self_ty.span.edition().rust_2021() { + if self_ty.span.edition().at_least_rust_2021() { let msg = "trait objects must include the `dyn` keyword"; let label = "add `dyn` keyword before this trait"; let mut diag = diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 07f8dd948e2f..89877280a739 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -867,7 +867,7 @@ impl<'tcx> TypeFolder> for ImplTraitInTraitCollector<'_, 'tcx> { }); self.types.insert(proj.def_id, (infer_ty, proj.args)); // Recurse into bounds - for (pred, pred_span) in self.interner().explicit_item_bounds(proj.def_id).arg_iter_copied(self.interner(), proj.args) { + for (pred, pred_span) in self.interner().explicit_item_bounds(proj.def_id).iter_instantiated_copied(self.interner(), proj.args) { let pred = pred.fold_with(self); let pred = self.ocx.normalize( &ObligationCause::misc(self.span, self.body_id), @@ -2149,7 +2149,7 @@ pub(super) fn check_type_bounds<'tcx>( let obligations: Vec<_> = tcx .explicit_item_bounds(trait_ty.def_id) - .arg_iter_copied(tcx, rebased_args) + .iter_instantiated_copied(tcx, rebased_args) .map(|(concrete_ty_bound, span)| { debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound); traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound) diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 5ff33763e13c..def7a3a9d885 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -409,7 +409,7 @@ fn fn_sig_suggestion<'tcx>( let asyncness = if tcx.asyncness(assoc.def_id).is_async() { output = if let ty::Alias(_, alias_ty) = *output.kind() { tcx.explicit_item_bounds(alias_ty.def_id) - .arg_iter_copied(tcx, alias_ty.args) + .iter_instantiated_copied(tcx, alias_ty.args) .find_map(|(bound, _)| bound.as_projection_clause()?.no_bound_vars()?.term.ty()) .unwrap_or_else(|| { span_bug!( diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 443d072f9924..4e194f1c381c 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1567,7 +1567,7 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { }); for (bound, bound_span) in tcx .explicit_item_bounds(opaque_ty.def_id) - .arg_iter_copied(tcx, opaque_ty.args) + .iter_instantiated_copied(tcx, opaque_ty.args) { let bound = self.wfcx.normalize(bound_span, None, bound); self.wfcx.register_obligations(traits::wf::predicate_obligations( diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 1c9070600dbe..979b101e7fe2 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -66,7 +66,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen let opaque_ty_id = tcx.hir().local_def_id_to_hir_id(opaque_def_id.expect_local()); let opaque_ty_node = tcx.hir().get(opaque_ty_id); let Node::Item(&Item { - kind: ItemKind::OpaqueTy(OpaqueTy { lifetime_mapping, .. }), + kind: ItemKind::OpaqueTy(OpaqueTy { lifetime_mapping: Some(lifetime_mapping), .. }), .. }) = opaque_ty_node else { diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 199cdabb7e98..1ef257e87d69 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -145,7 +145,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc let mut collector = OpaqueTypeLifetimeCollector { tcx, root_def_id: item_def_id.to_def_id(), variances }; let id_args = ty::GenericArgs::identity_for_item(tcx, item_def_id); - for (pred, _) in tcx.explicit_item_bounds(item_def_id).arg_iter_copied(tcx, id_args) { + for (pred, _) in tcx.explicit_item_bounds(item_def_id).iter_instantiated_copied(tcx, id_args) { debug!(?pred); // We only ignore opaque type args if the opaque type is the outermost type. diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index f2a43cc414d3..119ed2fa4082 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -551,8 +551,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } for ty in [first_ty, second_ty] { - for (clause, _) in - self.tcx.explicit_item_bounds(rpit_def_id).arg_iter_copied(self.tcx, args) + for (clause, _) in self + .tcx + .explicit_item_bounds(rpit_def_id) + .iter_instantiated_copied(self.tcx, args) { let pred = clause.kind().rebind(match clause.kind().skip_binder() { ty::ClauseKind::Trait(trait_pred) => { diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index e7df9ecf383e..affeee55e790 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -177,7 +177,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ty, self.tcx .explicit_item_bounds(def_id) - .arg_iter_copied(self.tcx, args) + .iter_instantiated_copied(self.tcx, args) .map(|(c, s)| (c.as_predicate(), s)), ), ty::Dynamic(ref object_type, ..) => { @@ -720,13 +720,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => self .tcx .explicit_item_bounds(def_id) - .arg_iter_copied(self.tcx, args) + .iter_instantiated_copied(self.tcx, args) .find_map(|(p, s)| get_future_output(p.as_predicate(), s))?, ty::Error(_) => return None, ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => self .tcx .explicit_item_bounds(proj.def_id) - .arg_iter_copied(self.tcx, proj.args) + .iter_instantiated_copied(self.tcx, proj.args) .find_map(|(p, s)| get_future_output(p.as_predicate(), s))?, _ => span_bug!( self.tcx.def_span(expr_def_id), diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index bd7e7a671e6b..94f64a1ffdb6 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -860,7 +860,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .resolve_fully_qualified_call(span, item_name, ty.normalized, qself.span, hir_id) .and_then(|r| { // lint bare trait if the method is found in the trait - if span.edition().rust_2021() && let Some(mut diag) = self.tcx.sess.diagnostic().steal_diagnostic(qself.span, StashKey::TraitMissingMethod) { + if span.edition().at_least_rust_2021() && let Some(mut diag) = self.tcx.sess.diagnostic().steal_diagnostic(qself.span, StashKey::TraitMissingMethod) { diag.emit(); } Ok(r) @@ -890,7 +890,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // emit or cancel the diagnostic for bare traits - if span.edition().rust_2021() && let Some(mut diag) = self.tcx.sess.diagnostic().steal_diagnostic(qself.span, StashKey::TraitMissingMethod) { + if span.edition().at_least_rust_2021() && let Some(mut diag) = self.tcx.sess.diagnostic().steal_diagnostic(qself.span, StashKey::TraitMissingMethod) { if trait_missing_method { // cancel the diag for bare traits when meeting `MyTrait::missing_method` diag.cancel(); @@ -908,7 +908,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error, None, Expectation::NoExpectation, - trait_missing_method && span.edition().rust_2021(), // emits missing method for trait only after edition 2021 + trait_missing_method && span.edition().at_least_rust_2021(), // emits missing method for trait only after edition 2021 ) { e.emit(); } diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs index ec4e7f7f88af..4efe95c4dc56 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs @@ -32,7 +32,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); // Rust 2021 and later is already using the new prelude - if span.rust_2021() { + if span.at_least_rust_2021() { return; } @@ -203,7 +203,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pick: &Pick<'tcx>, ) { // Rust 2021 and later is already using the new prelude - if span.rust_2021() { + if span.at_least_rust_2021() { return; } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 9ef97243c5e0..05eed1923d1a 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -437,7 +437,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // this case used to be allowed by the compiler, // so we do a future-compat lint here for the 2015 edition // (see https://github.com/rust-lang/rust/issues/46906) - if self.tcx.sess.rust_2018() { + if self.tcx.sess.at_least_rust_2018() { self.tcx.sess.emit_err(MethodCallOnUnknownRawPointee { span }); } else { self.tcx.struct_span_lint_hir( @@ -1592,7 +1592,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { if let Some(method_name) = self.method_name { // Some trait methods are excluded for arrays before 2021. // (`array.into_iter()` wants a slice iterator for compatibility.) - if self_ty.is_array() && !method_name.span.rust_2021() { + if self_ty.is_array() && !method_name.span.at_least_rust_2021() { let trait_def = self.tcx.trait_def(trait_ref.def_id); if trait_def.skip_array_during_method_dispatch { return ProbeResult::NoMatch; diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index f77a4d16b5f7..fb81a8395d79 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -2001,7 +2001,7 @@ fn should_do_rust_2021_incompatible_closure_captures_analysis( tcx: TyCtxt<'_>, closure_id: hir::HirId, ) -> bool { - if tcx.sess.rust_2021() { + if tcx.sess.at_least_rust_2021() { return false; } @@ -2247,5 +2247,5 @@ fn truncate_capture_for_optimization( fn enable_precise_capture(span: Span) -> bool { // We use span here to ensure that if the closure was generated by a macro with a different // edition. - span.rust_2021() + span.at_least_rust_2021() } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index cf6c7f70de3f..2329a1f63cec 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -3,7 +3,6 @@ // substitutions. use crate::FnCtxt; -use hir::def_id::LocalDefId; use rustc_data_structures::unord::ExtendUnord; use rustc_errors::{ErrorGuaranteed, StashKey}; use rustc_hir as hir; @@ -11,13 +10,12 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; -use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt}; +use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; use std::mem; -use std::ops::ControlFlow; /////////////////////////////////////////////////////////////////////////// // Entry point @@ -565,23 +563,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let hidden_type = self.resolve(decl.hidden_type, &decl.hidden_type.span); let opaque_type_key = self.resolve(opaque_type_key, &decl.hidden_type.span); - struct RecursionChecker { - def_id: LocalDefId, - } - impl<'tcx> ty::TypeVisitor> for RecursionChecker { - type BreakTy = (); - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { - if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *t.kind() { - if def_id == self.def_id.to_def_id() { - return ControlFlow::Break(()); - } - } - t.super_visit_with(self) - } - } - if hidden_type - .visit_with(&mut RecursionChecker { def_id: opaque_type_key.def_id }) - .is_break() + if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind() + && alias_ty.def_id == opaque_type_key.def_id.to_def_id() + && alias_ty.args == opaque_type_key.args { continue; } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index bf46f9881d47..8e3c76d6a4b4 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -403,7 +403,7 @@ impl<'tcx> InferCtxt<'tcx> { let future_trait = self.tcx.require_lang_item(LangItem::Future, None); let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0]; - self.tcx.explicit_item_bounds(def_id).arg_iter_copied(self.tcx, args).find_map( + self.tcx.explicit_item_bounds(def_id).iter_instantiated_copied(self.tcx, args).find_map( |(predicate, _)| { predicate .kind() diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 90f0b4ce401d..945136fbff2e 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -591,7 +591,7 @@ impl<'tcx> InferCtxt<'tcx> { let tcx = self.tcx; let item_bounds = tcx.explicit_item_bounds(def_id); - for (predicate, _) in item_bounds.arg_iter_copied(tcx, args) { + for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) { let predicate = predicate.fold_with(&mut BottomUpFolder { tcx, ty_op: |ty| match *ty.kind() { diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index 1e1ecd3fb947..2bc6546ba28d 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -295,7 +295,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { let bounds = tcx.item_bounds(alias_ty.def_id); trace!("{:#?}", bounds.skip_binder()); bounds - .arg_iter(tcx, alias_ty.args) + .iter_instantiated(tcx, alias_ty.args) .filter_map(|p| p.as_type_outlives_clause()) .filter_map(|p| p.no_bound_vars()) .map(|OutlivesPredicate(_, r)| r) diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 3f420f19efe1..5b417e008cf2 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -251,6 +251,7 @@ pub struct Config { pub input: Input, pub output_dir: Option, pub output_file: Option, + pub ice_file: Option, pub file_loader: Option>, pub locale_resources: &'static [&'static str], @@ -315,6 +316,7 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se config.lint_caps, config.make_codegen_backend, registry.clone(), + config.ice_file, ); if let Some(parse_sess_created) = config.parse_sess_created { @@ -346,7 +348,11 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se ) } -pub fn try_print_query_stack(handler: &Handler, num_frames: Option) { +pub fn try_print_query_stack( + handler: &Handler, + num_frames: Option, + file: Option, +) { eprintln!("query stack during panic:"); // Be careful relying on global state here: this code is called from @@ -358,7 +364,8 @@ pub fn try_print_query_stack(handler: &Handler, num_frames: Option) { QueryCtxt::new(icx.tcx), icx.query, handler, - num_frames + num_frames, + file, )) } else { 0 diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 09141afd1370..5c6c3491b388 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -67,6 +67,7 @@ fn mk_session(handler: &mut EarlyErrorHandler, matches: getopts::Matches) -> (Se None, None, "", + None, ); (sess, cfg) } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 035ea2414f76..12d33f06309b 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -70,6 +70,7 @@ pub fn create_session( Box Box + Send>, >, descriptions: Registry, + ice_file: Option, ) -> (Session, Box) { let codegen_backend = if let Some(make_codegen_backend) = make_codegen_backend { make_codegen_backend(&sopts) @@ -111,6 +112,7 @@ pub fn create_session( file_loader, target_override, rustc_version_str().unwrap_or("unknown"), + ice_file, ); codegen_backend.init(&sess); diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 6522e449386c..7c701fd4fe16 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -956,11 +956,11 @@ pub trait LintContext: Sized { db.span_note(glob_reexport_span, format!("the name `{}` in the {} namespace is supposed to be publicly re-exported here", name, namespace)); db.span_note(private_item_span, "but the private item here shadows it".to_owned()); } - BuiltinLintDiagnostics::UnusedQualifications { path_span, unqualified_path } => { + BuiltinLintDiagnostics::UnusedQualifications { removal_span } => { db.span_suggestion_verbose( - path_span, - "replace it with the unqualified path", - unqualified_path, + removal_span, + "remove the unnecessary path segments", + "", Applicability::MachineApplicable ); } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index c9ee2da6fdf8..0c80141a756d 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -978,6 +978,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { /// Returns `true` if the lint's feature is enabled. // FIXME only emit this once for each attribute, instead of repeating it 4 times for // pre-expansion lints, post-expansion lints, `shallow_lint_levels_on` and `lint_expectations`. + #[track_caller] fn check_gated_lint(&self, lint_id: LintId, span: Span) -> bool { if let Some(feature) = lint_id.lint.feature_gate { if !self.sess.features_untracked().enabled(feature) { @@ -1015,6 +1016,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] + #[track_caller] pub(crate) fn struct_lint( &self, lint: &'static Lint, @@ -1028,6 +1030,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { struct_lint_level(self.sess, lint, level, src, span, msg, decorate) } + #[track_caller] pub fn emit_spanned_lint( &self, lint: &'static Lint, @@ -1040,6 +1043,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { }); } + #[track_caller] pub fn emit_lint(&self, lint: &'static Lint, decorate: impl for<'a> DecorateLint<'a, ()>) { let (level, src) = self.lint_level(lint); struct_lint_level(self.sess, lint, level, src, None, decorate.msg(), |lint| { diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index d5f0290767ac..79b0b32bef24 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -117,7 +117,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { for (assoc_pred, assoc_pred_span) in cx .tcx .explicit_item_bounds(proj.projection_ty.def_id) - .arg_iter_copied(cx.tcx, &proj.projection_ty.args) + .iter_instantiated_copied(cx.tcx, &proj.projection_ty.args) { let assoc_pred = assoc_pred.fold_with(proj_replacer); let Ok(assoc_pred) = traits::fully_normalize( diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index f6ffd46b1fe0..10ebe29dfce6 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -551,10 +551,8 @@ pub enum BuiltinLintDiagnostics { private_item_span: Span, }, UnusedQualifications { - /// The span of the unnecessarily-qualified path. - path_span: Span, - /// The replacement unqualified path. - unqualified_path: Ident, + /// The span of the unnecessarily-qualified path to remove. + removal_span: Span, }, } diff --git a/compiler/rustc_metadata/src/foreign_modules.rs b/compiler/rustc_metadata/src/foreign_modules.rs index d1c2f3104d07..154eb684f119 100644 --- a/compiler/rustc_metadata/src/foreign_modules.rs +++ b/compiler/rustc_metadata/src/foreign_modules.rs @@ -1,19 +1,28 @@ +use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; use rustc_hir::def::DefKind; +use rustc_hir::def_id::DefId; +use rustc_middle::query::LocalCrate; use rustc_middle::ty::TyCtxt; use rustc_session::cstore::ForeignModule; -pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec { - let mut modules = Vec::new(); +pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> FxIndexMap { + let mut modules = FxIndexMap::default(); + + // We need to collect all the `ForeignMod`, even if they are empty. for id in tcx.hir().items() { if !matches!(tcx.def_kind(id.owner_id), DefKind::ForeignMod) { continue; } + + let def_id = id.owner_id.to_def_id(); let item = tcx.hir().item(id); - if let hir::ItemKind::ForeignMod { items, .. } = item.kind { + + if let hir::ItemKind::ForeignMod { abi, items } = item.kind { let foreign_items = items.iter().map(|it| it.id.owner_id.to_def_id()).collect(); - modules.push(ForeignModule { foreign_items, def_id: id.owner_id.to_def_id() }); + modules.insert(def_id, ForeignModule { def_id, abi, foreign_items }); } } + modules } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 9e0bf81d58dc..ca5043cc2633 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -1,15 +1,17 @@ use rustc_ast::{NestedMetaItem, CRATE_NODE_ID}; use rustc_attr as attr; use rustc_data_structures::fx::FxHashSet; -use rustc_hir as hir; -use rustc_hir::def::DefKind; +use rustc_middle::query::LocalCrate; use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt}; use rustc_session::config::CrateType; -use rustc_session::cstore::{DllCallingConvention, DllImport, NativeLib, PeImportNameType}; +use rustc_session::cstore::{ + DllCallingConvention, DllImport, ForeignModule, NativeLib, PeImportNameType, +}; use rustc_session::parse::feature_err; use rustc_session::search_paths::PathKind; use rustc_session::utils::NativeLibKind; use rustc_session::Session; +use rustc_span::def_id::{DefId, LOCAL_CRATE}; use rustc_span::symbol::{sym, Symbol}; use rustc_target::spec::abi::Abi; @@ -66,10 +68,12 @@ fn find_bundled_library( None } -pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec { +pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec { let mut collector = Collector { tcx, libs: Vec::new() }; - for id in tcx.hir().items() { - collector.process_item(id); + if tcx.sess.opts.unstable_opts.link_directives { + for module in tcx.foreign_modules(LOCAL_CRATE).values() { + collector.process_module(module); + } } collector.process_command_line(); collector.libs @@ -88,29 +92,20 @@ struct Collector<'tcx> { } impl<'tcx> Collector<'tcx> { - fn process_item(&mut self, id: rustc_hir::ItemId) { - if !matches!(self.tcx.def_kind(id.owner_id), DefKind::ForeignMod) { - return; - } + fn process_module(&mut self, module: &ForeignModule) { + let ForeignModule { def_id, abi, ref foreign_items } = *module; + let def_id = def_id.expect_local(); - let it = self.tcx.hir().item(id); - let hir::ItemKind::ForeignMod { abi, items: foreign_mod_items } = it.kind else { - return; - }; + let sess = self.tcx.sess; if matches!(abi, Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic) { return; } // Process all of the #[link(..)]-style arguments - let sess = self.tcx.sess; let features = self.tcx.features(); - if !sess.opts.unstable_opts.link_directives { - return; - } - - for m in self.tcx.hir().attrs(it.hir_id()).iter().filter(|a| a.has_name(sym::link)) { + for m in self.tcx.get_attrs(def_id, sym::link) { let Some(items) = m.meta_item_list() else { continue; }; @@ -340,9 +335,9 @@ impl<'tcx> Collector<'tcx> { if name.as_str().contains('\0') { sess.emit_err(errors::RawDylibNoNul { span: name_span }); } - foreign_mod_items + foreign_items .iter() - .map(|child_item| { + .map(|&child_item| { self.build_dll_import( abi, import_name_type.map(|(import_name_type, _)| import_name_type), @@ -352,21 +347,12 @@ impl<'tcx> Collector<'tcx> { .collect() } _ => { - for child_item in foreign_mod_items { - if self.tcx.def_kind(child_item.id.owner_id).has_codegen_attrs() - && self - .tcx - .codegen_fn_attrs(child_item.id.owner_id) - .link_ordinal - .is_some() + for &child_item in foreign_items { + if self.tcx.def_kind(child_item).has_codegen_attrs() + && self.tcx.codegen_fn_attrs(child_item).link_ordinal.is_some() { - let link_ordinal_attr = self - .tcx - .hir() - .attrs(child_item.id.owner_id.into()) - .iter() - .find(|a| a.has_name(sym::link_ordinal)) - .unwrap(); + let link_ordinal_attr = + self.tcx.get_attr(child_item, sym::link_ordinal).unwrap(); sess.emit_err(errors::LinkOrdinalRawDylib { span: link_ordinal_attr.span, }); @@ -384,7 +370,7 @@ impl<'tcx> Collector<'tcx> { filename, kind, cfg, - foreign_module: Some(it.owner_id.to_def_id()), + foreign_module: Some(def_id.to_def_id()), verbatim, dll_imports, }); @@ -476,10 +462,10 @@ impl<'tcx> Collector<'tcx> { } } - fn i686_arg_list_size(&self, item: &hir::ForeignItemRef) -> usize { + fn i686_arg_list_size(&self, item: DefId) -> usize { let argument_types: &List> = self.tcx.erase_late_bound_regions( self.tcx - .type_of(item.id.owner_id) + .type_of(item) .instantiate_identity() .fn_sig(self.tcx) .inputs() @@ -505,8 +491,10 @@ impl<'tcx> Collector<'tcx> { &self, abi: Abi, import_name_type: Option, - item: &hir::ForeignItemRef, + item: DefId, ) -> DllImport { + let span = self.tcx.def_span(item); + let calling_convention = if self.tcx.sess.target.arch == "x86" { match abi { Abi::C { .. } | Abi::Cdecl { .. } => DllCallingConvention::C, @@ -520,29 +508,29 @@ impl<'tcx> Collector<'tcx> { DllCallingConvention::Vectorcall(self.i686_arg_list_size(item)) } _ => { - self.tcx.sess.emit_fatal(errors::UnsupportedAbiI686 { span: item.span }); + self.tcx.sess.emit_fatal(errors::UnsupportedAbiI686 { span }); } } } else { match abi { Abi::C { .. } | Abi::Win64 { .. } | Abi::System { .. } => DllCallingConvention::C, _ => { - self.tcx.sess.emit_fatal(errors::UnsupportedAbi { span: item.span }); + self.tcx.sess.emit_fatal(errors::UnsupportedAbi { span }); } } }; - let codegen_fn_attrs = self.tcx.codegen_fn_attrs(item.id.owner_id); + let codegen_fn_attrs = self.tcx.codegen_fn_attrs(item); let import_name_type = codegen_fn_attrs .link_ordinal .map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord))); DllImport { - name: codegen_fn_attrs.link_name.unwrap_or(item.ident.name), + name: codegen_fn_attrs.link_name.unwrap_or(self.tcx.item_name(item)), import_name_type, calling_convention, - span: item.span, - is_fn: self.tcx.def_kind(item.id.owner_id).is_fn_like(), + span, + is_fn: self.tcx.def_kind(item).is_fn_like(), } } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 8fa1d365728a..9e67bb655d42 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -34,7 +34,7 @@ use rustc_session::cstore::{ use rustc_session::Session; use rustc_span::hygiene::ExpnIndex; use rustc_span::symbol::{kw, Ident, Symbol}; -use rustc_span::{self, BytePos, ExpnId, Pos, Span, SyntaxContext, DUMMY_SP}; +use rustc_span::{self, BytePos, ExpnId, Pos, Span, SpanData, SyntaxContext, DUMMY_SP}; use proc_macro::bridge::client::ProcMacro; use std::iter::TrustedLen; @@ -513,11 +513,26 @@ impl<'a, 'tcx> Decodable> for ExpnId { impl<'a, 'tcx> Decodable> for Span { fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Span { + let mode = SpanEncodingMode::decode(decoder); + let data = match mode { + SpanEncodingMode::Direct => SpanData::decode(decoder), + SpanEncodingMode::Shorthand(position) => decoder.with_position(position, |decoder| { + let mode = SpanEncodingMode::decode(decoder); + debug_assert!(matches!(mode, SpanEncodingMode::Direct)); + SpanData::decode(decoder) + }), + }; + Span::new(data.lo, data.hi, data.ctxt, data.parent) + } +} + +impl<'a, 'tcx> Decodable> for SpanData { + fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> SpanData { let ctxt = SyntaxContext::decode(decoder); let tag = u8::decode(decoder); if tag == TAG_PARTIAL_SPAN { - return DUMMY_SP.with_ctxt(ctxt); + return DUMMY_SP.with_ctxt(ctxt).data(); } debug_assert!(tag == TAG_VALID_SPAN_LOCAL || tag == TAG_VALID_SPAN_FOREIGN); @@ -612,7 +627,7 @@ impl<'a, 'tcx> Decodable> for Span { let hi = hi + source_file.translated_source_file.start_pos; // Do not try to decode parent for foreign spans. - Span::new(lo, hi, ctxt, None) + SpanData { lo, hi, ctxt, parent: None } } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 848535fb3952..a8815ee0908d 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -403,10 +403,8 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { .contains(&id) }) }, - native_libraries: |tcx, LocalCrate| native_libs::collect(tcx), - foreign_modules: |tcx, LocalCrate| { - foreign_modules::collect(tcx).into_iter().map(|m| (m.def_id, m)).collect() - }, + native_libraries: native_libs::collect, + foreign_modules: foreign_modules::collect, // Returns a map from a sufficiently visible external item (i.e., an // external item that is visible from at least one local module) to a diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 2785732727f9..ac86110f2bdb 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -37,7 +37,7 @@ use rustc_session::config::{CrateType, OptLevel}; use rustc_session::cstore::{ForeignModule, LinkagePreference, NativeLib}; use rustc_span::hygiene::{ExpnIndex, HygieneEncodeContext, MacroKind}; use rustc_span::symbol::{sym, Symbol}; -use rustc_span::{self, ExternalSource, FileName, SourceFile, Span, SyntaxContext}; +use rustc_span::{self, ExternalSource, FileName, SourceFile, Span, SpanData, SyntaxContext}; use std::borrow::Borrow; use std::collections::hash_map::Entry; use std::hash::Hash; @@ -53,6 +53,7 @@ pub(super) struct EncodeContext<'a, 'tcx> { tables: TableBuilders, lazy_state: LazyState, + span_shorthands: FxHashMap, type_shorthands: FxHashMap, usize>, predicate_shorthands: FxHashMap, usize>, @@ -177,8 +178,20 @@ impl<'a, 'tcx> Encodable> for ExpnId { impl<'a, 'tcx> Encodable> for Span { fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) { - let span = self.data(); + match s.span_shorthands.entry(*self) { + Entry::Occupied(o) => SpanEncodingMode::Shorthand(*o.get()).encode(s), + Entry::Vacant(v) => { + let position = s.opaque.position(); + v.insert(position); + SpanEncodingMode::Direct.encode(s); + self.data().encode(s); + } + } + } +} +impl<'a, 'tcx> Encodable> for SpanData { + fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) { // Don't serialize any `SyntaxContext`s from a proc-macro crate, // since we don't load proc-macro dependencies during serialization. // This means that any hygiene information from macros used *within* @@ -213,7 +226,7 @@ impl<'a, 'tcx> Encodable> for Span { if s.is_proc_macro { SyntaxContext::root().encode(s); } else { - span.ctxt.encode(s); + self.ctxt.encode(s); } if self.is_dummy() { @@ -221,18 +234,18 @@ impl<'a, 'tcx> Encodable> for Span { } // The Span infrastructure should make sure that this invariant holds: - debug_assert!(span.lo <= span.hi); + debug_assert!(self.lo <= self.hi); - if !s.source_file_cache.0.contains(span.lo) { + if !s.source_file_cache.0.contains(self.lo) { let source_map = s.tcx.sess.source_map(); - let source_file_index = source_map.lookup_source_file_idx(span.lo); + let source_file_index = source_map.lookup_source_file_idx(self.lo); s.source_file_cache = (source_map.files()[source_file_index].clone(), source_file_index); } let (ref source_file, source_file_index) = s.source_file_cache; - debug_assert!(source_file.contains(span.lo)); + debug_assert!(source_file.contains(self.lo)); - if !source_file.contains(span.hi) { + if !source_file.contains(self.hi) { // Unfortunately, macro expansion still sometimes generates Spans // that malformed in this way. return TAG_PARTIAL_SPAN.encode(s); @@ -286,11 +299,11 @@ impl<'a, 'tcx> Encodable> for Span { // Encode the start position relative to the file start, so we profit more from the // variable-length integer encoding. - let lo = span.lo - source_file.start_pos; + let lo = self.lo - source_file.start_pos; // Encode length which is usually less than span.hi and profits more // from the variable-length integer encoding that we use. - let len = span.hi - span.lo; + let len = self.hi - self.lo; tag.encode(s); lo.encode(s); @@ -2182,6 +2195,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) { feat: tcx.features(), tables: Default::default(), lazy_state: LazyState::NoNode, + span_shorthands: Default::default(), type_shorthands: Default::default(), predicate_shorthands: Default::default(), source_file_cache, diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index f6087fbe8f66..0bc16fc64ff7 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -66,6 +66,12 @@ const METADATA_VERSION: u8 = 8; /// unsigned integer, and further followed by the rustc version string. pub const METADATA_HEADER: &[u8] = &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION]; +#[derive(Encodable, Decodable)] +enum SpanEncodingMode { + Shorthand(usize), + Direct, +} + /// A value of type T referred to by its absolute position /// in the metadata, and which can be decoded lazily. /// diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 20230217afca..6ce1ad8f43e8 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -278,6 +278,7 @@ pub fn explain_lint_level_source( /// // ^^^^^^^^^^^^^^^^^^^^^ returns `&mut DiagnosticBuilder` by default /// ) /// ``` +#[track_caller] pub fn struct_lint_level( sess: &Session, lint: &'static Lint, @@ -291,6 +292,7 @@ pub fn struct_lint_level( ) { // Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to // the "real" work. + #[track_caller] fn struct_lint_level_impl( sess: &Session, lint: &'static Lint, diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index c4601a1fb418..02fd6ed7ba6b 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -100,6 +100,8 @@ bitflags! { const REALLOCATOR = 1 << 18; /// `#[rustc_allocator_zeroed]`: a hint to LLVM that the function only allocates zeroed memory. const ALLOCATOR_ZEROED = 1 << 19; + /// `#[no_builtins]`: indicates that disable implicit builtin knowledge of functions for the function. + const NO_BUILTINS = 1 << 20; } } diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 16addc2dc1e7..f4133dfbc95b 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -56,6 +56,8 @@ impl<'tcx> MonoItem<'tcx> { } } + // Note: if you change how item size estimates work, you might need to + // change NON_INCR_MIN_CGU_SIZE as well. pub fn size_estimate(&self, tcx: TyCtxt<'tcx>) -> usize { match *self { MonoItem::Fn(instance) => { @@ -248,8 +250,14 @@ pub struct CodegenUnit<'tcx> { /// Auxiliary info about a `MonoItem`. #[derive(Copy, Clone, PartialEq, Debug, HashStable)] pub struct MonoItemData { + /// A cached copy of the result of `MonoItem::instantiation_mode`, where + /// `GloballyShared` maps to `false` and `LocalCopy` maps to `true`. + pub inlined: bool, + pub linkage: Linkage, pub visibility: Visibility, + + /// A cached copy of the result of `MonoItem::size_estimate`. pub size_estimate: usize, } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index c304245ca39b..062adc9ec54c 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1579,7 +1579,7 @@ rustc_queries! { } /// Returns a list of all `extern` blocks of a crate. - query foreign_modules(_: CrateNum) -> &'tcx FxHashMap { + query foreign_modules(_: CrateNum) -> &'tcx FxIndexMap { arena_cache desc { "looking up the foreign modules of a linked crate" } separate_provide_extern diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index bf9f5846ed9f..4ef70107f194 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -294,6 +294,14 @@ impl<'tcx> Const<'tcx> { Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize)) } + /// Attempts to convert to a `ValTree` + pub fn try_to_valtree(self) -> Option> { + match self.kind() { + ty::ConstKind::Value(valtree) => Some(valtree), + _ => None, + } + } + #[inline] /// Attempts to evaluate the given constant to bits. Can fail to evaluate in the presence of /// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8bb13edbe950..1a23fa802100 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1860,6 +1860,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`, /// typically generated by `#[derive(LintDiagnostic)]`). + #[track_caller] pub fn emit_spanned_lint( self, lint: &'static Lint, @@ -1880,6 +1881,7 @@ impl<'tcx> TyCtxt<'tcx> { /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_lint_hir( self, lint: &'static Lint, @@ -1896,6 +1898,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Emit a lint from a lint struct (some type that implements `DecorateLint`, typically /// generated by `#[derive(LintDiagnostic)]`). + #[track_caller] pub fn emit_lint( self, lint: &'static Lint, @@ -1911,6 +1914,7 @@ impl<'tcx> TyCtxt<'tcx> { /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_lint_node( self, lint: &'static Lint, diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index 12af84564943..97dab5cb47e8 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -610,8 +610,12 @@ impl<'tcx, 's, I: IntoIterator> EarlyBinder where I::Item: TypeFoldable>, { - pub fn arg_iter(self, tcx: TyCtxt<'tcx>, args: &'s [GenericArg<'tcx>]) -> ArgIter<'s, 'tcx, I> { - ArgIter { it: self.value.into_iter(), tcx, args } + pub fn iter_instantiated( + self, + tcx: TyCtxt<'tcx>, + args: &'s [GenericArg<'tcx>], + ) -> IterInstantiated<'s, 'tcx, I> { + IterInstantiated { it: self.value.into_iter(), tcx, args } } /// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity), @@ -621,13 +625,13 @@ where } } -pub struct ArgIter<'s, 'tcx, I: IntoIterator> { +pub struct IterInstantiated<'s, 'tcx, I: IntoIterator> { it: I::IntoIter, tcx: TyCtxt<'tcx>, args: &'s [GenericArg<'tcx>], } -impl<'tcx, I: IntoIterator> Iterator for ArgIter<'_, 'tcx, I> +impl<'tcx, I: IntoIterator> Iterator for IterInstantiated<'_, 'tcx, I> where I::Item: TypeFoldable>, { @@ -642,7 +646,7 @@ where } } -impl<'tcx, I: IntoIterator> DoubleEndedIterator for ArgIter<'_, 'tcx, I> +impl<'tcx, I: IntoIterator> DoubleEndedIterator for IterInstantiated<'_, 'tcx, I> where I::IntoIter: DoubleEndedIterator, I::Item: TypeFoldable>, @@ -652,7 +656,7 @@ where } } -impl<'tcx, I: IntoIterator> ExactSizeIterator for ArgIter<'_, 'tcx, I> +impl<'tcx, I: IntoIterator> ExactSizeIterator for IterInstantiated<'_, 'tcx, I> where I::IntoIter: ExactSizeIterator, I::Item: TypeFoldable>, @@ -664,12 +668,12 @@ where I::Item: Deref, ::Target: Copy + TypeFoldable>, { - pub fn arg_iter_copied( + pub fn iter_instantiated_copied( self, tcx: TyCtxt<'tcx>, args: &'s [GenericArg<'tcx>], - ) -> ArgIterCopied<'s, 'tcx, I> { - ArgIterCopied { it: self.value.into_iter(), tcx, args } + ) -> IterInstantiatedCopied<'s, 'tcx, I> { + IterInstantiatedCopied { it: self.value.into_iter(), tcx, args } } /// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity), @@ -681,13 +685,13 @@ where } } -pub struct ArgIterCopied<'a, 'tcx, I: IntoIterator> { +pub struct IterInstantiatedCopied<'a, 'tcx, I: IntoIterator> { it: I::IntoIter, tcx: TyCtxt<'tcx>, args: &'a [GenericArg<'tcx>], } -impl<'tcx, I: IntoIterator> Iterator for ArgIterCopied<'_, 'tcx, I> +impl<'tcx, I: IntoIterator> Iterator for IterInstantiatedCopied<'_, 'tcx, I> where I::Item: Deref, ::Target: Copy + TypeFoldable>, @@ -703,7 +707,7 @@ where } } -impl<'tcx, I: IntoIterator> DoubleEndedIterator for ArgIterCopied<'_, 'tcx, I> +impl<'tcx, I: IntoIterator> DoubleEndedIterator for IterInstantiatedCopied<'_, 'tcx, I> where I::IntoIter: DoubleEndedIterator, I::Item: Deref, @@ -716,7 +720,7 @@ where } } -impl<'tcx, I: IntoIterator> ExactSizeIterator for ArgIterCopied<'_, 'tcx, I> +impl<'tcx, I: IntoIterator> ExactSizeIterator for IterInstantiatedCopied<'_, 'tcx, I> where I::IntoIter: ExactSizeIterator, I::Item: Deref, diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 338590717d05..70a35f137d80 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -347,7 +347,7 @@ impl<'tcx> GenericPredicates<'tcx> { tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>, ) -> impl Iterator, Span)> + DoubleEndedIterator + ExactSizeIterator { - EarlyBinder::bind(self.predicates).arg_iter_copied(tcx, args) + EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args) } #[instrument(level = "debug", skip(self, tcx))] diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 3591acdea565..e5633223464a 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -928,7 +928,7 @@ pub trait PrettyPrinter<'tcx>: let mut is_sized = false; let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new(); - for (predicate, _) in bounds.arg_iter_copied(tcx, args) { + for (predicate, _) in bounds.iter_instantiated_copied(tcx, args) { let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { @@ -1932,7 +1932,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { fn path_crate(mut self, cnum: CrateNum) -> Result { self.empty_path = true; if cnum == LOCAL_CRATE { - if self.tcx.sess.rust_2018() { + if self.tcx.sess.at_least_rust_2018() { // We add the `crate::` keyword on Rust 2018, only when desired. if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { write!(self, "{}", kw::Crate)?; diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index cdb0b2240a47..f9c1ca9a8b16 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -15,7 +15,6 @@ use hir::def::DefKind; use polonius_engine::Atom; use rustc_data_structures::captures::Captures; use rustc_data_structures::intern::Interned; -use rustc_error_messages::DiagnosticMessage; use rustc_errors::{DiagnosticArgValue, ErrorGuaranteed, IntoDiagnosticArg, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -1991,7 +1990,7 @@ impl<'tcx> Ty<'tcx> { pub fn new_error_with_message>( tcx: TyCtxt<'tcx>, span: S, - msg: impl Into, + msg: impl Into, ) -> Ty<'tcx> { let reported = tcx.sess.delay_span_bug(span, msg); Ty::new(tcx, Error(reported)) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index b4852ab88815..553b76cad4ed 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -19,7 +19,7 @@ use rustc_index::bit_set::GrowableBitSet; use rustc_macros::HashStable; use rustc_session::Limit; use rustc_span::sym; -use rustc_target::abi::{Integer, IntegerType, Size, TargetDataLayout}; +use rustc_target::abi::{Integer, IntegerType, Size}; use rustc_target::spec::abi::Abi; use smallvec::SmallVec; use std::{fmt, iter}; @@ -1085,7 +1085,7 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn needs_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { // Avoid querying in simple cases. - match needs_drop_components(self, &tcx.data_layout) { + match needs_drop_components(tcx, self) { Err(AlwaysRequiresDrop) => true, Ok(components) => { let query_ty = match *components { @@ -1118,7 +1118,7 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn has_significant_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { // Avoid querying in simple cases. - match needs_drop_components(self, &tcx.data_layout) { + match needs_drop_components(tcx, self) { Err(AlwaysRequiresDrop) => true, Ok(components) => { let query_ty = match *components { @@ -1278,10 +1278,10 @@ impl<'tcx> ExplicitSelf<'tcx> { /// *any* of the returned types need drop. Returns `Err(AlwaysRequiresDrop)` if /// this type always needs drop. pub fn needs_drop_components<'tcx>( + tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, - target_layout: &TargetDataLayout, ) -> Result; 2]>, AlwaysRequiresDrop> { - match ty.kind() { + match *ty.kind() { ty::Infer(ty::FreshIntTy(_)) | ty::Infer(ty::FreshFloatTy(_)) | ty::Bool @@ -1303,11 +1303,11 @@ pub fn needs_drop_components<'tcx>( ty::Dynamic(..) | ty::Error(_) => Err(AlwaysRequiresDrop), - ty::Slice(ty) => needs_drop_components(*ty, target_layout), + ty::Slice(ty) => needs_drop_components(tcx, ty), ty::Array(elem_ty, size) => { - match needs_drop_components(*elem_ty, target_layout) { + match needs_drop_components(tcx, elem_ty) { Ok(v) if v.is_empty() => Ok(v), - res => match size.try_to_bits(target_layout.pointer_size) { + res => match size.try_to_target_usize(tcx) { // Arrays of size zero don't need drop, even if their element // type does. Some(0) => Ok(SmallVec::new()), @@ -1321,7 +1321,7 @@ pub fn needs_drop_components<'tcx>( } // If any field needs drop, then the whole tuple does. ty::Tuple(fields) => fields.iter().try_fold(SmallVec::new(), move |mut acc, elem| { - acc.extend(needs_drop_components(elem, target_layout)?); + acc.extend(needs_drop_components(tcx, elem)?); Ok(acc) }), diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index c122230b8419..7756d5d48795 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -730,5 +730,5 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Precise capture is enabled if user is using Rust Edition 2021 or higher. fn enable_precise_capture(closure_span: Span) -> bool { - closure_span.rust_2021() + closure_span.at_least_rust_2021() } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 54096abb2e0c..71aef53192f4 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -248,7 +248,8 @@ where } let size_estimate = mono_item.size_estimate(cx.tcx); - cgu.items_mut().insert(mono_item, MonoItemData { linkage, visibility, size_estimate }); + cgu.items_mut() + .insert(mono_item, MonoItemData { inlined: false, linkage, visibility, size_estimate }); // Get all inlined items that are reachable from `mono_item` without // going via another root item. This includes drop-glue, functions from @@ -263,6 +264,7 @@ where for inlined_item in reachable_inlined_items { // This is a CGU-private copy. cgu.items_mut().entry(inlined_item).or_insert_with(|| MonoItemData { + inlined: true, linkage: Linkage::Internal, visibility: Visibility::Default, size_estimate: inlined_item.size_estimate(cx.tcx), @@ -316,6 +318,60 @@ fn merge_codegen_units<'tcx>( let mut cgu_contents: FxHashMap> = codegen_units.iter().map(|cgu| (cgu.name(), vec![cgu.name()])).collect(); + // If N is the maximum number of CGUs, and the CGUs are sorted from largest + // to smallest, we repeatedly find which CGU in codegen_units[N..] has the + // greatest overlap of inlined items with codegen_units[N-1], merge that + // CGU into codegen_units[N-1], then re-sort by size and repeat. + // + // We use inlined item overlap to guide this merging because it minimizes + // duplication of inlined items, which makes LLVM be faster and generate + // better and smaller machine code. + // + // Why merge into codegen_units[N-1]? We want CGUs to have similar sizes, + // which means we don't want codegen_units[0..N] (the already big ones) + // getting any bigger, if we can avoid it. When we have more than N CGUs + // then at least one of the biggest N will have to grow. codegen_units[N-1] + // is the smallest of those, and so has the most room to grow. + let max_codegen_units = cx.tcx.sess.codegen_units().as_usize(); + while codegen_units.len() > max_codegen_units { + // Sort small CGUs to the back. + codegen_units.sort_by_key(|cgu| cmp::Reverse(cgu.size_estimate())); + + let cgu_dst = &codegen_units[max_codegen_units - 1]; + + // Find the CGU that overlaps the most with `cgu_dst`. In the case of a + // tie, favour the earlier (bigger) CGU. + let mut max_overlap = 0; + let mut max_overlap_i = max_codegen_units; + for (i, cgu_src) in codegen_units.iter().enumerate().skip(max_codegen_units) { + if cgu_src.size_estimate() <= max_overlap { + // None of the remaining overlaps can exceed `max_overlap`, so + // stop looking. + break; + } + + let overlap = compute_inlined_overlap(cgu_dst, cgu_src); + if overlap > max_overlap { + max_overlap = overlap; + max_overlap_i = i; + } + } + + let mut cgu_src = codegen_units.swap_remove(max_overlap_i); + let cgu_dst = &mut codegen_units[max_codegen_units - 1]; + + // Move the items from `cgu_src` to `cgu_dst`. Some of them may be + // duplicate inlined items, in which case the destination CGU is + // unaffected. Recalculate size estimates afterwards. + cgu_dst.items_mut().extend(cgu_src.items_mut().drain()); + cgu_dst.compute_size_estimate(); + + // Record that `cgu_dst` now contains all the stuff that was in + // `cgu_src` before. + let mut consumed_cgu_names = cgu_contents.remove(&cgu_src.name()).unwrap(); + cgu_contents.get_mut(&cgu_dst.name()).unwrap().append(&mut consumed_cgu_names); + } + // Having multiple CGUs can drastically speed up compilation. But for // non-incremental builds, tiny CGUs slow down compilation *and* result in // worse generated code. So we don't allow CGUs smaller than this (unless @@ -323,24 +379,22 @@ fn merge_codegen_units<'tcx>( // common in larger programs, so this isn't all that large. const NON_INCR_MIN_CGU_SIZE: usize = 1800; - // Repeatedly merge the two smallest codegen units as long as: - // - we have more CGUs than the upper limit, or - // - (Non-incremental builds only) the user didn't specify a CGU count, and - // there are multiple CGUs, and some are below the minimum size. + // Repeatedly merge the two smallest codegen units as long as: it's a + // non-incremental build, and the user didn't specify a CGU count, and + // there are multiple CGUs, and some are below the minimum size. // // The "didn't specify a CGU count" condition is because when an explicit // count is requested we observe it as closely as possible. For example, // the `compiler_builtins` crate sets `codegen-units = 10000` and it's // critical they aren't merged. Also, some tests use explicit small values // and likewise won't work if small CGUs are merged. - while codegen_units.len() > cx.tcx.sess.codegen_units().as_usize() - || (cx.tcx.sess.opts.incremental.is_none() - && matches!(cx.tcx.sess.codegen_units(), CodegenUnits::Default(_)) - && codegen_units.len() > 1 - && codegen_units.iter().any(|cgu| cgu.size_estimate() < NON_INCR_MIN_CGU_SIZE)) + while cx.tcx.sess.opts.incremental.is_none() + && matches!(cx.tcx.sess.codegen_units(), CodegenUnits::Default(_)) + && codegen_units.len() > 1 + && codegen_units.iter().any(|cgu| cgu.size_estimate() < NON_INCR_MIN_CGU_SIZE) { // Sort small cgus to the back. - codegen_units.sort_by_key(|cgu| cmp::Reverse(cgu.size_estimate())); + codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate())); let mut smallest = codegen_units.pop().unwrap(); let second_smallest = codegen_units.last_mut().unwrap(); @@ -351,16 +405,7 @@ fn merge_codegen_units<'tcx>( second_smallest.items_mut().extend(smallest.items_mut().drain()); second_smallest.compute_size_estimate(); - // Record that `second_smallest` now contains all the stuff that was - // in `smallest` before. - let mut consumed_cgu_names = cgu_contents.remove(&smallest.name()).unwrap(); - cgu_contents.get_mut(&second_smallest.name()).unwrap().append(&mut consumed_cgu_names); - - debug!( - "CodegenUnit {} merged into CodegenUnit {}", - smallest.name(), - second_smallest.name() - ); + // Don't update `cgu_contents`, that's only for incremental builds. } let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx); @@ -439,6 +484,25 @@ fn merge_codegen_units<'tcx>( } } +/// Compute the combined size of all inlined items that appear in both `cgu1` +/// and `cgu2`. +fn compute_inlined_overlap<'tcx>(cgu1: &CodegenUnit<'tcx>, cgu2: &CodegenUnit<'tcx>) -> usize { + // Either order works. We pick the one that involves iterating over fewer + // items. + let (src_cgu, dst_cgu) = + if cgu1.items().len() <= cgu2.items().len() { (cgu1, cgu2) } else { (cgu2, cgu1) }; + + let mut overlap = 0; + for (item, data) in src_cgu.items().iter() { + if data.inlined { + if dst_cgu.items().contains_key(item) { + overlap += data.size_estimate; + } + } + } + overlap +} + fn internalize_symbols<'tcx>( cx: &PartitioningCx<'_, 'tcx>, codegen_units: &mut [CodegenUnit<'tcx>], @@ -870,19 +934,16 @@ fn debug_dump<'a, 'tcx: 'a>(tcx: TyCtxt<'tcx>, label: &str, cgus: &[CodegenUnit< all_cgu_sizes.push(cgu.size_estimate()); for (item, data) in cgu.items() { - match item.instantiation_mode(tcx) { - InstantiationMode::GloballyShared { .. } => { - root_items += 1; - root_size += data.size_estimate; - } - InstantiationMode::LocalCopy => { - if inlined_items.insert(item) { - unique_inlined_items += 1; - unique_inlined_size += data.size_estimate; - } - placed_inlined_items += 1; - placed_inlined_size += data.size_estimate; + if !data.inlined { + root_items += 1; + root_size += data.size_estimate; + } else { + if inlined_items.insert(item) { + unique_inlined_items += 1; + unique_inlined_size += data.size_estimate; } + placed_inlined_items += 1; + placed_inlined_size += data.size_estimate; } } } @@ -937,10 +998,7 @@ fn debug_dump<'a, 'tcx: 'a>(tcx: TyCtxt<'tcx>, label: &str, cgus: &[CodegenUnit< let symbol_name = item.symbol_name(tcx).name; let symbol_hash_start = symbol_name.rfind('h'); let symbol_hash = symbol_hash_start.map_or("", |i| &symbol_name[i..]); - let kind = match item.instantiation_mode(tcx) { - InstantiationMode::GloballyShared { .. } => "root", - InstantiationMode::LocalCopy => "inlined", - }; + let kind = if !data.inlined { "root" } else { "inlined" }; let size = data.size_estimate; let _ = with_no_trimmed_paths!(writeln!( s, diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 8455803ad0c5..c3cf6437afa0 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -247,7 +247,7 @@ impl<'a> Parser<'a> { self.sess.span_diagnostic.struct_span_err(sp, m) } - pub fn span_bug>(&self, sp: S, m: impl Into) -> ! { + pub fn span_bug>(&self, sp: S, m: impl Into) -> ! { self.sess.span_diagnostic.span_bug(sp, m) } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 7ede4fbc3d90..3ecdbc362481 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1309,7 +1309,7 @@ impl<'a> Parser<'a> { /// Assuming we have just parsed `.`, continue parsing into an expression. fn parse_dot_suffix(&mut self, self_arg: P, lo: Span) -> PResult<'a, P> { - if self.token.uninterpolated_span().rust_2018() && self.eat_keyword(kw::Await) { + if self.token.uninterpolated_span().at_least_rust_2018() && self.eat_keyword(kw::Await) { return Ok(self.mk_await_expr(self_arg, lo)); } @@ -1442,8 +1442,8 @@ impl<'a> Parser<'a> { self.parse_expr_let() } else if self.eat_keyword(kw::Underscore) { Ok(self.mk_expr(self.prev_token.span, ExprKind::Underscore)) - } else if self.token.uninterpolated_span().rust_2018() { - // `Span::rust_2018()` is somewhat expensive; don't get it repeatedly. + } else if self.token.uninterpolated_span().at_least_rust_2018() { + // `Span:.at_least_rust_2018()` is somewhat expensive; don't get it repeatedly. if self.check_keyword(kw::Async) { if self.is_async_block() { // Check for `async {` and `async move {`. @@ -2230,7 +2230,7 @@ impl<'a> Parser<'a> { let movability = if self.eat_keyword(kw::Static) { Movability::Static } else { Movability::Movable }; - let asyncness = if self.token.uninterpolated_span().rust_2018() { + let asyncness = if self.token.uninterpolated_span().at_least_rust_2018() { self.parse_asyncness(Case::Sensitive) } else { Async::No @@ -3014,7 +3014,7 @@ impl<'a> Parser<'a> { fn is_try_block(&self) -> bool { self.token.is_keyword(kw::Try) && self.look_ahead(1, |t| *t == token::OpenDelim(Delimiter::Brace)) - && self.token.uninterpolated_span().rust_2018() + && self.token.uninterpolated_span().at_least_rust_2018() } /// Parses an `async move? {...}` expression. diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index e4d843b7c8bc..2e1a61e634e6 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1210,7 +1210,8 @@ impl<'a> Parser<'a> { fn parse_constness_(&mut self, case: Case, is_closure: bool) -> Const { // Avoid const blocks and const closures to be parsed as const items if (self.check_const_closure() == is_closure) - && self.look_ahead(1, |t| t != &token::OpenDelim(Delimiter::Brace)) + && !self + .look_ahead(1, |t| *t == token::OpenDelim(Delimiter::Brace) || t.is_whole_block()) && self.eat_keyword_case(kw::Const, case) { Const::Yes(self.prev_token.uninterpolated_span()) diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index fdf365178474..14891c45d81a 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -8,7 +8,6 @@ use crate::errors::{ TrailingVertNotAllowed, UnexpectedLifetimeInPattern, UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern, }; -use crate::fluent_generated as fluent; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor}; use rustc_ast::ptr::P; @@ -214,41 +213,25 @@ impl<'a> Parser<'a> { if let PatKind::Or(pats) = &pat.kind { let span = pat.span; - - if trailing_vert { - // We already emitted an error and suggestion to remove the trailing vert. Don't - // emit again. - - // FIXME(#100717): pass `TopLevelOrPatternNotAllowed::* { sub: None }` to - // `delay_span_bug()` instead of fluent message - self.sess.span_diagnostic.delay_span_bug( - span, - match syntax_loc { - PatternLocation::LetBinding => { - fluent::parse_or_pattern_not_allowed_in_let_binding - } - PatternLocation::FunctionParameter => { - fluent::parse_or_pattern_not_allowed_in_fn_parameters - } - }, - ); + let pat = pprust::pat_to_string(&pat); + let sub = if pats.len() == 1 { + Some(TopLevelOrPatternNotAllowedSugg::RemoveLeadingVert { span, pat }) } else { - let pat = pprust::pat_to_string(&pat); - let sub = if pats.len() == 1 { - Some(TopLevelOrPatternNotAllowedSugg::RemoveLeadingVert { span, pat }) - } else { - Some(TopLevelOrPatternNotAllowedSugg::WrapInParens { span, pat }) - }; + Some(TopLevelOrPatternNotAllowedSugg::WrapInParens { span, pat }) + }; - self.sess.emit_err(match syntax_loc { - PatternLocation::LetBinding => { - TopLevelOrPatternNotAllowed::LetBinding { span, sub } - } - PatternLocation::FunctionParameter => { - TopLevelOrPatternNotAllowed::FunctionParameter { span, sub } - } - }); + let mut err = self.sess.create_err(match syntax_loc { + PatternLocation::LetBinding => { + TopLevelOrPatternNotAllowed::LetBinding { span, sub } + } + PatternLocation::FunctionParameter => { + TopLevelOrPatternNotAllowed::FunctionParameter { span, sub } + } + }); + if trailing_vert { + err.delay_as_bug(); } + err.emit(); } Ok((pat, colon)) diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index a29b696aea83..3bb50b05aa34 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -608,7 +608,7 @@ impl<'a> Parser<'a> { /// Is a `dyn B0 + ... + Bn` type allowed here? fn is_explicit_dyn_type(&mut self) -> bool { self.check_keyword(kw::Dyn) - && (self.token.uninterpolated_span().rust_2018() + && (self.token.uninterpolated_span().at_least_rust_2018() || self.look_ahead(1, |t| { (t.can_begin_bound() || t.kind == TokenKind::BinOp(token::Star)) && !can_continue_type_after_non_fn_ident(t) diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 7de84db211ed..88452ccdf052 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -109,6 +109,8 @@ pub struct Argument<'a> { pub struct FormatSpec<'a> { /// Optionally specified character to fill alignment with. pub fill: Option, + /// Span of the optionally specified fill character. + pub fill_span: Option, /// Optionally specified alignment. pub align: Alignment, /// The `+` or `-` flag. @@ -264,7 +266,7 @@ impl<'a> Iterator for Parser<'a> { Some(String(self.string(pos + 1))) } else { let arg = self.argument(lbrace_end); - if let Some(rbrace_pos) = self.must_consume('}') { + if let Some(rbrace_pos) = self.consume_closing_brace(&arg) { if self.is_source_literal { let lbrace_byte_pos = self.to_span_index(pos); let rbrace_byte_pos = self.to_span_index(rbrace_pos); @@ -450,69 +452,51 @@ impl<'a> Parser<'a> { /// Forces consumption of the specified character. If the character is not /// found, an error is emitted. - fn must_consume(&mut self, c: char) -> Option { + fn consume_closing_brace(&mut self, arg: &Argument<'_>) -> Option { self.ws(); - if let Some(&(pos, maybe)) = self.cur.peek() { - if c == maybe { + let pos; + let description; + + if let Some(&(peek_pos, maybe)) = self.cur.peek() { + if maybe == '}' { self.cur.next(); - Some(pos) - } else { - let pos = self.to_span_index(pos); - let description = format!("expected `'}}'`, found `{maybe:?}`"); - let label = "expected `}`".to_owned(); - let (note, secondary_label) = if c == '}' { - ( - Some( - "if you intended to print `{`, you can escape it using `{{`".to_owned(), - ), - self.last_opening_brace - .map(|sp| ("because of this opening brace".to_owned(), sp)), - ) - } else { - (None, None) - }; - self.errors.push(ParseError { - description, - note, - label, - span: pos.to(pos), - secondary_label, - should_be_replaced_with_positional_argument: false, - }); - None + return Some(peek_pos); } + + pos = peek_pos; + description = format!("expected `'}}'`, found `{maybe:?}`"); } else { - let description = format!("expected `{c:?}` but string was terminated"); + description = "expected `'}'` but string was terminated".to_owned(); // point at closing `"` - let pos = self.input.len() - if self.append_newline { 1 } else { 0 }; - let pos = self.to_span_index(pos); - if c == '}' { - let label = format!("expected `{c:?}`"); - let (note, secondary_label) = if c == '}' { - ( - Some( - "if you intended to print `{`, you can escape it using `{{`".to_owned(), - ), - self.last_opening_brace - .map(|sp| ("because of this opening brace".to_owned(), sp)), - ) - } else { - (None, None) - }; - self.errors.push(ParseError { - description, - note, - label, - span: pos.to(pos), - secondary_label, - should_be_replaced_with_positional_argument: false, - }); - } else { - self.err(description, format!("expected `{c:?}`"), pos.to(pos)); - } - None + pos = self.input.len() - if self.append_newline { 1 } else { 0 }; } + + let pos = self.to_span_index(pos); + + let label = "expected `'}'`".to_owned(); + let (note, secondary_label) = if arg.format.fill == Some('}') { + ( + Some("the character `'}'` is interpreted as a fill character because of the `:` that precedes it".to_owned()), + arg.format.fill_span.map(|sp| ("this is not interpreted as a formatting closing brace".to_owned(), sp)), + ) + } else { + ( + Some("if you intended to print `{`, you can escape it using `{{`".to_owned()), + self.last_opening_brace.map(|sp| ("because of this opening brace".to_owned(), sp)), + ) + }; + + self.errors.push(ParseError { + description, + note, + label, + span: pos.to(pos), + secondary_label, + should_be_replaced_with_positional_argument: false, + }); + + None } /// Consumes all whitespace characters until the first non-whitespace character @@ -608,6 +592,7 @@ impl<'a> Parser<'a> { fn format(&mut self) -> FormatSpec<'a> { let mut spec = FormatSpec { fill: None, + fill_span: None, align: AlignUnknown, sign: None, alternate: false, @@ -625,9 +610,10 @@ impl<'a> Parser<'a> { } // fill character - if let Some(&(_, c)) = self.cur.peek() { + if let Some(&(idx, c)) = self.cur.peek() { if let Some((_, '>' | '<' | '^')) = self.cur.clone().nth(1) { spec.fill = Some(c); + spec.fill_span = Some(self.span(idx, idx + 1)); self.cur.next(); } } @@ -722,6 +708,7 @@ impl<'a> Parser<'a> { fn inline_asm(&mut self) -> FormatSpec<'a> { let mut spec = FormatSpec { fill: None, + fill_span: None, align: AlignUnknown, sign: None, alternate: false, diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs index 45314e2fb550..0c594f9104cc 100644 --- a/compiler/rustc_parse_format/src/tests.rs +++ b/compiler/rustc_parse_format/src/tests.rs @@ -9,6 +9,7 @@ fn same(fmt: &'static str, p: &[Piece<'static>]) { fn fmtdflt() -> FormatSpec<'static> { return FormatSpec { fill: None, + fill_span: None, align: AlignUnknown, sign: None, alternate: false, @@ -128,6 +129,7 @@ fn format_type() { position_span: InnerSpan { start: 2, end: 3 }, format: FormatSpec { fill: None, + fill_span: None, align: AlignUnknown, sign: None, alternate: false, @@ -152,6 +154,7 @@ fn format_align_fill() { position_span: InnerSpan { start: 2, end: 3 }, format: FormatSpec { fill: None, + fill_span: None, align: AlignRight, sign: None, alternate: false, @@ -173,6 +176,7 @@ fn format_align_fill() { position_span: InnerSpan { start: 2, end: 3 }, format: FormatSpec { fill: Some('0'), + fill_span: Some(InnerSpan::new(4, 5)), align: AlignLeft, sign: None, alternate: false, @@ -194,6 +198,7 @@ fn format_align_fill() { position_span: InnerSpan { start: 2, end: 3 }, format: FormatSpec { fill: Some('*'), + fill_span: Some(InnerSpan::new(4, 5)), align: AlignLeft, sign: None, alternate: false, @@ -218,6 +223,7 @@ fn format_counts() { position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { fill: None, + fill_span: None, align: AlignUnknown, sign: None, alternate: false, @@ -239,6 +245,7 @@ fn format_counts() { position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { fill: None, + fill_span: None, align: AlignUnknown, sign: None, alternate: false, @@ -260,6 +267,7 @@ fn format_counts() { position_span: InnerSpan { start: 2, end: 3 }, format: FormatSpec { fill: None, + fill_span: None, align: AlignUnknown, sign: None, alternate: false, @@ -281,6 +289,7 @@ fn format_counts() { position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { fill: None, + fill_span: None, align: AlignUnknown, sign: None, alternate: false, @@ -302,6 +311,7 @@ fn format_counts() { position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { fill: None, + fill_span: None, align: AlignUnknown, sign: None, alternate: false, @@ -323,6 +333,7 @@ fn format_counts() { position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { fill: None, + fill_span: None, align: AlignUnknown, sign: None, alternate: false, @@ -344,6 +355,7 @@ fn format_counts() { position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { fill: None, + fill_span: None, align: AlignUnknown, sign: None, alternate: false, @@ -368,6 +380,7 @@ fn format_flags() { position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { fill: None, + fill_span: None, align: AlignUnknown, sign: Some(Sign::Minus), alternate: false, @@ -389,6 +402,7 @@ fn format_flags() { position_span: InnerSpan { start: 2, end: 2 }, format: FormatSpec { fill: None, + fill_span: None, align: AlignUnknown, sign: Some(Sign::Plus), alternate: true, @@ -415,6 +429,7 @@ fn format_mixture() { position_span: InnerSpan { start: 7, end: 8 }, format: FormatSpec { fill: None, + fill_span: None, align: AlignUnknown, sign: None, alternate: false, diff --git a/compiler/rustc_query_system/messages.ftl b/compiler/rustc_query_system/messages.ftl index 49b423d1adeb..d5fed8fe179f 100644 --- a/compiler/rustc_query_system/messages.ftl +++ b/compiler/rustc_query_system/messages.ftl @@ -1,4 +1,5 @@ query_system_cycle = cycle detected when {$stack_bottom} + .note = see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information query_system_cycle_recursive_trait_alias = trait aliases cannot be recursive diff --git a/compiler/rustc_query_system/src/error.rs b/compiler/rustc_query_system/src/error.rs index cf2f04c7486b..e49e78cc7c41 100644 --- a/compiler/rustc_query_system/src/error.rs +++ b/compiler/rustc_query_system/src/error.rs @@ -57,6 +57,8 @@ pub struct Cycle { pub alias: Option, #[subdiagnostic] pub cycle_usage: Option, + #[note] + pub note_span: (), } #[derive(Diagnostic)] diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index f45f7ca5da6d..d2140161f1d9 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -13,6 +13,7 @@ use rustc_session::Session; use rustc_span::Span; use std::hash::Hash; +use std::io::Write; use std::num::NonZeroU64; #[cfg(parallel_compiler)] @@ -607,6 +608,7 @@ pub(crate) fn report_cycle<'a, D: DepKind>( alias, cycle_usage: cycle_usage, stack_count, + note_span: (), }; cycle_diag.into_diagnostic(&sess.parse_sess.span_diagnostic) @@ -617,30 +619,50 @@ pub fn print_query_stack( mut current_query: Option, handler: &Handler, num_frames: Option, + mut file: Option, ) -> usize { // Be careful relying on global state here: this code is called from // a panic hook, which means that the global `Handler` may be in a weird // state if it was responsible for triggering the panic. - let mut i = 0; + let mut count_printed = 0; + let mut count_total = 0; let query_map = qcx.try_collect_active_jobs(); + if let Some(ref mut file) = file { + let _ = writeln!(file, "\n\nquery stack during panic:"); + } while let Some(query) = current_query { - if Some(i) == num_frames { - break; - } let Some(query_info) = query_map.as_ref().and_then(|map| map.get(&query)) else { break; }; - let mut diag = Diagnostic::new( - Level::FailureNote, - format!("#{} [{:?}] {}", i, query_info.query.dep_kind, query_info.query.description), - ); - diag.span = query_info.job.span.into(); - handler.force_print_diagnostic(diag); + if Some(count_printed) < num_frames || num_frames.is_none() { + // Only print to stderr as many stack frames as `num_frames` when present. + let mut diag = Diagnostic::new( + Level::FailureNote, + format!( + "#{} [{:?}] {}", + count_printed, query_info.query.dep_kind, query_info.query.description + ), + ); + diag.span = query_info.job.span.into(); + handler.force_print_diagnostic(diag); + count_printed += 1; + } + + if let Some(ref mut file) = file { + let _ = writeln!( + file, + "#{} [{:?}] {}", + count_total, query_info.query.dep_kind, query_info.query.description + ); + } current_query = query_info.job.parent; - i += 1; + count_total += 1; } - i + if let Some(ref mut file) = file { + let _ = writeln!(file, "end of query stack"); + } + count_printed } diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index dc35c8b176f5..3228e8d52f06 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -440,7 +440,7 @@ impl Resolver<'_, '_> { // If we are not in Rust 2018 edition, then we don't make any further // suggestions. - if !tcx.sess.rust_2018() { + if !tcx.sess.at_least_rust_2018() { continue; } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index d3dcdfa42754..2cfde2f62d8c 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1203,7 +1203,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if filter_fn(res) { // create the path let mut segms = path_segments.clone(); - if lookup_ident.span.rust_2018() { + if lookup_ident.span.at_least_rust_2018() { // crate-local absolute paths start with `crate::` in edition 2018 // FIXME: may also be stabilized for Rust 2015 (Issues #45477, #44660) segms.insert(0, ast::PathSegment::from_ident(crate_name)); @@ -1268,7 +1268,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { path_segments.push(ast::PathSegment::from_ident(ident)); let is_extern_crate_that_also_appears_in_prelude = - name_binding.is_extern_crate() && lookup_ident.span.rust_2018(); + name_binding.is_extern_crate() && lookup_ident.span.at_least_rust_2018(); if !is_extern_crate_that_also_appears_in_prelude { // add the module to the lookup @@ -1315,7 +1315,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { &filter_fn, ); - if lookup_ident.span.rust_2018() { + if lookup_ident.span.at_least_rust_2018() { let extern_prelude_names = self.extern_prelude.clone(); for (ident, _) in extern_prelude_names.into_iter() { if ident.span.from_expansion() { @@ -1568,7 +1568,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { "consider adding an explicit import of `{ident}` to disambiguate" )) } - if b.is_extern_crate() && ident.span.rust_2018() { + if b.is_extern_crate() && ident.span.at_least_rust_2018() { help_msgs.push(format!("use `::{ident}` to refer to this {thing} unambiguously")) } match misc { @@ -1973,7 +1973,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if fst.ident.name == kw::PathRoot && !snd.ident.is_path_segment_keyword() => {} // `ident::...` on 2018. (Some(fst), _) - if fst.ident.span.rust_2018() && !fst.ident.is_path_segment_keyword() => + if fst.ident.span.at_least_rust_2018() && !fst.ident.is_path_segment_keyword() => { // Insert a placeholder that's later replaced by `self`/`super`/etc. path.insert(0, Segment::from_ident(Ident::empty())); diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 520fab1f0c83..de4314447698 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1417,13 +1417,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { )); continue; } - if name == kw::PathRoot && ident.span.rust_2018() { + if name == kw::PathRoot && ident.span.at_least_rust_2018() { module = Some(ModuleOrUniformRoot::ExternPrelude); continue; } if name == kw::PathRoot && ident.span.is_rust_2015() - && self.tcx.sess.rust_2018() + && self.tcx.sess.at_least_rust_2018() { // `::a::b` from 2015 macro on 2018 global edition module = Some(ModuleOrUniformRoot::CrateRootAndExternPrelude); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 846a1ffe09b1..05128a51016a 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3911,8 +3911,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { && path[0].ident.name != kw::PathRoot && path[0].ident.name != kw::DollarCrate { + let last_segment = *path.last().unwrap(); let unqualified_result = { - match self.resolve_path(&[*path.last().unwrap()], Some(ns), None) { + match self.resolve_path(&[last_segment], Some(ns), None) { PathResult::NonModule(path_res) => path_res.expect_full_res(), PathResult::Module(ModuleOrUniformRoot::Module(module)) => { module.res().unwrap() @@ -3928,8 +3929,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { finalize.path_span, "unnecessary qualification", lint::BuiltinLintDiagnostics::UnusedQualifications { - path_span: finalize.path_span, - unqualified_path: path.last().unwrap().ident + removal_span: finalize.path_span.until(last_segment.ident.span), } ) } diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index dc475e8c6d57..c53a355b533e 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -13,6 +13,7 @@ use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions}; use rustc_span::hygiene::{ExpnHash, ExpnId}; use rustc_span::symbol::Symbol; use rustc_span::Span; +use rustc_target::spec::abi::Abi; use rustc_target::spec::Target; use std::any::Any; @@ -147,6 +148,7 @@ pub enum DllCallingConvention { pub struct ForeignModule { pub foreign_items: Vec, pub def_id: DefId, + pub abi: Abi, } #[derive(Copy, Clone, Debug, HashStable_Generic)] diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 194f7201ff35..b0a67c564ce1 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -117,6 +117,7 @@ pub fn feature_err_issue( /// Construct a future incompatibility diagnostic for a feature gate. /// /// This diagnostic is only a warning and *does not cause compilation to fail*. +#[track_caller] pub fn feature_warn(sess: &ParseSess, feature: Symbol, span: Span, explain: &'static str) { feature_warn_issue(sess, feature, span, GateIssue::Language, explain); } @@ -129,6 +130,7 @@ pub fn feature_warn(sess: &ParseSess, feature: Symbol, span: Span, explain: &'st /// Almost always, you want to use this for a language feature. If so, prefer `feature_warn`. #[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::untranslatable_diagnostic)] +#[track_caller] pub fn feature_warn_issue( sess: &ParseSess, feature: Symbol, @@ -229,6 +231,7 @@ impl ParseSess { Some(sm.clone()), None, fallback_bundle, + None, ); ParseSess::with_span_handler(handler, sm) } @@ -259,12 +262,20 @@ impl ParseSess { pub fn with_silent_emitter(fatal_note: Option) -> Self { let fallback_bundle = fallback_fluent_bundle(Vec::new(), false); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let fatal_handler = - Handler::with_tty_emitter(ColorConfig::Auto, false, None, None, None, fallback_bundle); + let fatal_handler = Handler::with_tty_emitter( + ColorConfig::Auto, + false, + None, + None, + None, + fallback_bundle, + None, + ); let handler = Handler::with_emitter( false, None, Box::new(SilentEmitter { fatal_handler, fatal_note }), + None, ); ParseSess::with_span_handler(handler, sm) } @@ -351,6 +362,7 @@ impl ParseSess { self.create_warning(warning).emit() } + #[track_caller] pub fn create_note<'a>( &'a self, note: impl IntoDiagnostic<'a, Noted>, @@ -358,10 +370,12 @@ impl ParseSess { note.into_diagnostic(&self.span_diagnostic) } + #[track_caller] pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, Noted>) -> Noted { self.create_note(note).emit() } + #[track_caller] pub fn create_fatal<'a>( &'a self, fatal: impl IntoDiagnostic<'a, !>, @@ -369,6 +383,7 @@ impl ParseSess { fatal.into_diagnostic(&self.span_diagnostic) } + #[track_caller] pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, !>) -> ! { self.create_fatal(fatal).emit() } @@ -383,16 +398,19 @@ impl ParseSess { } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { self.span_diagnostic.struct_warn(msg) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_fatal(&self, msg: impl Into) -> DiagnosticBuilder<'_, !> { self.span_diagnostic.struct_fatal(msg) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_diagnostic( &self, msg: impl Into, diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 5be122ffbdeb..146bb11bd3a7 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -677,7 +677,7 @@ impl Session { pub fn delay_span_bug>( &self, sp: S, - msg: impl Into, + msg: impl Into, ) -> ErrorGuaranteed { self.diagnostic().delay_span_bug(sp, msg) } @@ -995,18 +995,18 @@ impl Session { } /// Are we allowed to use features from the Rust 2018 edition? - pub fn rust_2018(&self) -> bool { - self.edition().rust_2018() + pub fn at_least_rust_2018(&self) -> bool { + self.edition().at_least_rust_2018() } /// Are we allowed to use features from the Rust 2021 edition? - pub fn rust_2021(&self) -> bool { - self.edition().rust_2021() + pub fn at_least_rust_2021(&self) -> bool { + self.edition().at_least_rust_2021() } /// Are we allowed to use features from the Rust 2024 edition? - pub fn rust_2024(&self) -> bool { - self.edition().rust_2024() + pub fn at_least_rust_2024(&self) -> bool { + self.edition().at_least_rust_2024() } /// Returns `true` if we should use the PLT for shared library calls. @@ -1392,6 +1392,7 @@ pub fn build_session( file_loader: Option>, target_override: Option, cfg_version: &'static str, + ice_file: Option, ) -> Session { // FIXME: This is not general enough to make the warning lint completely override // normal diagnostic warnings, since the warning lint can also be denied and changed @@ -1440,6 +1441,7 @@ pub fn build_session( let span_diagnostic = rustc_errors::Handler::with_emitter_and_flags( emitter, sopts.unstable_opts.diagnostic_handler_flags(can_emit_warnings), + ice_file, ); let self_profiler = if let SwitchWithOptPath::Enabled(ref d) = sopts.unstable_opts.self_profile @@ -1731,7 +1733,7 @@ pub struct EarlyErrorHandler { impl EarlyErrorHandler { pub fn new(output: ErrorOutputType) -> Self { let emitter = mk_emitter(output); - Self { handler: rustc_errors::Handler::with_emitter(true, None, emitter) } + Self { handler: rustc_errors::Handler::with_emitter(true, None, emitter, None) } } pub fn abort_if_errors(&self) { @@ -1745,7 +1747,7 @@ impl EarlyErrorHandler { self.handler.abort_if_errors(); let emitter = mk_emitter(output); - self.handler = Handler::with_emitter(true, None, emitter); + self.handler = Handler::with_emitter(true, None, emitter, None); } #[allow(rustc::untranslatable_diagnostic)] diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 6af6cfe58f18..0e5de1e74d32 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -119,8 +119,12 @@ impl<'tcx> Tables<'tcx> { TyKind::RigidTy(RigidTy::Array(self.intern_ty(*ty), opaque(constant))) } ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(self.intern_ty(*ty))), - ty::RawPtr(_) => todo!(), - ty::Ref(_, _, _) => todo!(), + ty::RawPtr(ty::TypeAndMut { ty, mutbl }) => { + TyKind::RigidTy(RigidTy::RawPtr(self.intern_ty(*ty), mutbl.stable())) + } + ty::Ref(region, ty, mutbl) => { + TyKind::RigidTy(RigidTy::Ref(opaque(region), self.intern_ty(*ty), mutbl.stable())) + } ty::FnDef(_, _) => todo!(), ty::FnPtr(_) => todo!(), ty::Dynamic(_, _, _) => todo!(), diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index 02ac907f09a6..831eb6589e46 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -1,4 +1,4 @@ -use crate::rustc_internal::Opaque; +use crate::stable_mir::ty::Region; use crate::stable_mir::{self, ty::Ty}; #[derive(Clone, Debug)] @@ -137,8 +137,6 @@ pub enum Statement { Nop, } -type Region = Opaque; - // FIXME this is incomplete #[derive(Clone, Debug)] pub enum Rvalue { diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index e9f17f92c04a..7ae07efb729d 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -1,4 +1,4 @@ -use super::{with, DefId}; +use super::{mir::Mutability, with, DefId}; use crate::rustc_internal::Opaque; #[derive(Copy, Clone, Debug)] @@ -11,7 +11,7 @@ impl Ty { } type Const = Opaque; -type Region = Opaque; +pub(crate) type Region = Opaque; #[derive(Clone, Debug)] pub enum TyKind { @@ -29,6 +29,8 @@ pub enum RigidTy { Str, Array(Ty, Const), Slice(Ty), + RawPtr(Ty, Mutability), + Ref(Region, Ty, Mutability), Tuple(Vec), } diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs index f16db69aae23..608b8c24bde8 100644 --- a/compiler/rustc_span/src/edition.rs +++ b/compiler/rustc_span/src/edition.rs @@ -82,17 +82,17 @@ impl Edition { } /// Are we allowed to use features from the Rust 2018 edition? - pub fn rust_2018(self) -> bool { + pub fn at_least_rust_2018(self) -> bool { self >= Edition::Edition2018 } /// Are we allowed to use features from the Rust 2021 edition? - pub fn rust_2021(self) -> bool { + pub fn at_least_rust_2021(self) -> bool { self >= Edition::Edition2021 } /// Are we allowed to use features from the Rust 2024 edition? - pub fn rust_2024(self) -> bool { + pub fn at_least_rust_2024(self) -> bool { self >= Edition::Edition2024 } } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 5c56337d1e05..ecaa82874a3c 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -707,24 +707,28 @@ impl Span { self.ctxt().edition() } + /// Is this edition 2015? #[inline] pub fn is_rust_2015(self) -> bool { self.edition().is_rust_2015() } + /// Are we allowed to use features from the Rust 2018 edition? #[inline] - pub fn rust_2018(self) -> bool { - self.edition().rust_2018() + pub fn at_least_rust_2018(self) -> bool { + self.edition().at_least_rust_2018() } + /// Are we allowed to use features from the Rust 2021 edition? #[inline] - pub fn rust_2021(self) -> bool { - self.edition().rust_2021() + pub fn at_least_rust_2021(self) -> bool { + self.edition().at_least_rust_2021() } + /// Are we allowed to use features from the Rust 2024 edition? #[inline] - pub fn rust_2024(self) -> bool { - self.edition().rust_2024() + pub fn at_least_rust_2024(self) -> bool { + self.edition().at_least_rust_2024() } /// Returns the source callee. diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 03e7b3e7b402..3d2ea017d8f1 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -693,8 +693,8 @@ impl<'a, Ty> FnAbi<'a, Ty> { "avr" => avr::compute_abi_info(self), "loongarch64" => loongarch::compute_abi_info(cx, self), "m68k" => m68k::compute_abi_info(self), - "mips" => mips::compute_abi_info(cx, self), - "mips64" => mips64::compute_abi_info(cx, self), + "mips" | "mips32r6" => mips::compute_abi_info(cx, self), + "mips64" | "mips64r6" => mips64::compute_abi_info(cx, self), "powerpc" => powerpc::compute_abi_info(self), "powerpc64" => powerpc64::compute_abi_info(cx, self), "s390x" => s390x::compute_abi_info(cx, self), diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index e60b8e78e5d5..7c27732079b8 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -238,8 +238,8 @@ impl FromStr for InlineAsmArch { "powerpc64" => Ok(Self::PowerPC64), "hexagon" => Ok(Self::Hexagon), "loongarch64" => Ok(Self::LoongArch64), - "mips" => Ok(Self::Mips), - "mips64" => Ok(Self::Mips64), + "mips" | "mips32r6" => Ok(Self::Mips), + "mips64" | "mips64r6" => Ok(Self::Mips64), "s390x" => Ok(Self::S390x), "spirv" => Ok(Self::SpirV), "wasm32" => Ok(Self::Wasm32), diff --git a/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs index 1e066b271e28..983a449b006a 100644 --- a/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs @@ -6,7 +6,7 @@ pub fn target() -> Target { llvm_target: "mipsisa32r6-unknown-linux-gnu".into(), pointer_width: 32, data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), - arch: "mips".into(), + arch: "mips32r6".into(), options: TargetOptions { endian: Endian::Big, cpu: "mips32r6".into(), diff --git a/compiler/rustc_target/src/spec/mipsisa32r6el_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mipsisa32r6el_unknown_linux_gnu.rs index 4785929c1000..ec0facdfb7bf 100644 --- a/compiler/rustc_target/src/spec/mipsisa32r6el_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/mipsisa32r6el_unknown_linux_gnu.rs @@ -5,7 +5,7 @@ pub fn target() -> Target { llvm_target: "mipsisa32r6el-unknown-linux-gnu".into(), pointer_width: 32, data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), - arch: "mips".into(), + arch: "mips32r6".into(), options: TargetOptions { cpu: "mips32r6".into(), diff --git a/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs index 766ac7680644..16dd1c416f4f 100644 --- a/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs @@ -6,7 +6,7 @@ pub fn target() -> Target { llvm_target: "mipsisa64r6-unknown-linux-gnuabi64".into(), pointer_width: 64, data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".into(), - arch: "mips64".into(), + arch: "mips64r6".into(), options: TargetOptions { abi: "abi64".into(), endian: Endian::Big, diff --git a/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs index d2b07c654dcf..8d0a6aa8f514 100644 --- a/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs @@ -5,7 +5,7 @@ pub fn target() -> Target { llvm_target: "mipsisa64r6el-unknown-linux-gnuabi64".into(), pointer_width: 64, data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".into(), - arch: "mips64".into(), + arch: "mips64r6".into(), options: TargetOptions { abi: "abi64".into(), // NOTE(mips64r6) matches C toolchain diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 312bd38178fd..6efc1e7302c0 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -1,5 +1,5 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -use crate::traits::{self, ObligationCtxt}; +use crate::traits::{self, DefiningAnchor, ObligationCtxt}; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; @@ -80,7 +80,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { pub trait InferCtxtBuilderExt<'tcx> { fn enter_canonical_trait_query( - &mut self, + self, canonical_key: &Canonical<'tcx, K>, operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result, ) -> Result, NoSolution> @@ -108,7 +108,7 @@ impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> { /// have `'tcx` be free on this function so that we can talk about /// `K: TypeFoldable>`.) fn enter_canonical_trait_query( - &mut self, + self, canonical_key: &Canonical<'tcx, K>, operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result, ) -> Result, NoSolution> @@ -117,8 +117,9 @@ impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> { R: Debug + TypeFoldable>, Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>, { - let (infcx, key, canonical_inference_vars) = - self.build_with_canonical(DUMMY_SP, canonical_key); + let (infcx, key, canonical_inference_vars) = self + .with_opaque_type_inference(DefiningAnchor::Bubble) + .build_with_canonical(DUMMY_SP, canonical_key); let ocx = ObligationCtxt::new(&infcx); let value = operation(&ocx, key)?; ocx.make_canonicalized_query_response(canonical_inference_vars, value) diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index 3a1302e46baf..a8ba98bef6d9 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -148,7 +148,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>( ty::Adt(def, args) => { let sized_crit = def.sized_constraint(ecx.tcx()); - Ok(sized_crit.arg_iter_copied(ecx.tcx(), args).collect()) + Ok(sized_crit.iter_instantiated_copied(ecx.tcx(), args).collect()) } } } @@ -353,7 +353,8 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>( // FIXME(associated_const_equality): Also add associated consts to // the requirements here. if item.kind == ty::AssocKind::Type { - requirements.extend(tcx.item_bounds(item.def_id).arg_iter(tcx, trait_ref.args)); + requirements + .extend(tcx.item_bounds(item.def_id).iter_instantiated(tcx, trait_ref.args)); } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 56d5d698d909..e086489b1bcb 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2133,7 +2133,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { Where( obligation .predicate - .rebind(sized_crit.arg_iter_copied(self.tcx(), args).collect()), + .rebind(sized_crit.iter_instantiated_copied(self.tcx(), args).collect()), ) } diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 34ad6bd8c692..05ad4a4a12ab 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -78,6 +78,7 @@ mod rustc { use rustc_middle::ty::ParamEnv; use rustc_middle::ty::Ty; use rustc_middle::ty::TyCtxt; + use rustc_middle::ty::ValTree; /// The source and destination types of a transmutation. #[derive(TypeVisitable, Debug, Clone, Copy)] @@ -148,7 +149,17 @@ mod rustc { ); let variant = adt_def.non_enum_variant(); - let fields = c.to_valtree().unwrap_branch(); + let fields = match c.try_to_valtree() { + Some(ValTree::Branch(branch)) => branch, + _ => { + return Some(Self { + alignment: true, + lifetimes: true, + safety: true, + validity: true, + }); + } + }; let get_field = |name| { let (field_idx, _) = variant diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 3e6dfc1304f1..e173bba49be0 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -96,7 +96,7 @@ where return Some(Err(AlwaysRequiresDrop)); } - let components = match needs_drop_components(ty, &tcx.data_layout) { + let components = match needs_drop_components(tcx, ty) { Err(e) => return Some(Err(e)), Ok(components) => components, }; @@ -160,7 +160,7 @@ where queue_type(self, required); } } - ty::Array(..) | ty::Alias(..) | ty::Param(_) => { + ty::Alias(..) | ty::Array(..) | ty::Placeholder(_) | ty::Param(_) => { if ty == component { // Return the type to the caller: they may be able // to normalize further than we can. @@ -172,7 +172,31 @@ where queue_type(self, component); } } - _ => return Some(Err(AlwaysRequiresDrop)), + + ty::Foreign(_) | ty::Dynamic(..) => { + return Some(Err(AlwaysRequiresDrop)); + } + + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Str + | ty::Slice(_) + | ty::Ref(..) + | ty::RawPtr(..) + | ty::FnDef(..) + | ty::FnPtr(..) + | ty::Tuple(_) + | ty::Bound(..) + | ty::GeneratorWitness(..) + | ty::GeneratorWitnessMIR(..) + | ty::Never + | ty::Infer(_) + | ty::Error(_) => { + bug!("unexpected type returned by `needs_drop_components`: {component}") + } } } } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index f6302113e2a2..505f78d0e5fe 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -42,7 +42,7 @@ fn sized_constraint_for_ty<'tcx>( let adt_tys = adt.sized_constraint(tcx); debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", ty, adt_tys); adt_tys - .arg_iter_copied(tcx, args) + .iter_instantiated_copied(tcx, args) .flat_map(|ty| sized_constraint_for_ty(tcx, adtdef, ty)) .collect() } @@ -297,7 +297,7 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { for bound in self .tcx .item_bounds(unshifted_alias_ty.def_id) - .arg_iter(self.tcx, unshifted_alias_ty.args) + .iter_instantiated(self.tcx, unshifted_alias_ty.args) { bound.visit_with(self); } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index d287397aab3a..5bf66850f03d 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -604,6 +604,9 @@ pub mod alloc; // Private support modules mod panicking; +#[unstable(feature = "ice_to_disk", issue = "none")] +pub use panicking::panic_hook_with_disk_dump; + #[path = "../../backtrace/src/lib.rs"] #[allow(dead_code, unused_attributes, fuzzy_provenance_casts)] mod backtrace_rs; diff --git a/library/std/src/os/linux/raw.rs b/library/std/src/os/linux/raw.rs index c55ca8ba26e2..7c55e92502f8 100644 --- a/library/std/src/os/linux/raw.rs +++ b/library/std/src/os/linux/raw.rs @@ -94,7 +94,7 @@ mod arch { } } -#[cfg(target_arch = "mips")] +#[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] mod arch { use crate::os::raw::{c_long, c_ulong}; @@ -233,6 +233,7 @@ mod arch { #[cfg(any( target_arch = "loongarch64", target_arch = "mips64", + target_arch = "mips64r6", target_arch = "s390x", target_arch = "sparc64", target_arch = "riscv64", diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index a6a370409c0e..0e90d618ad43 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -234,7 +234,16 @@ where *hook = Hook::Custom(Box::new(move |info| hook_fn(&prev, info))); } +/// The default panic handler. fn default_hook(info: &PanicInfo<'_>) { + panic_hook_with_disk_dump(info, None) +} + +#[unstable(feature = "ice_to_disk", issue = "none")] +/// The implementation of the default panic handler. +/// +/// It can also write the backtrace to a given `path`. This functionality is used only by `rustc`. +pub fn panic_hook_with_disk_dump(info: &PanicInfo<'_>, path: Option<&crate::path::Path>) { // If this is a double panic, make sure that we print a backtrace // for this panic. Otherwise only print it if logging is enabled. let backtrace = if panic_count::get_count() >= 2 { @@ -256,7 +265,7 @@ fn default_hook(info: &PanicInfo<'_>) { let thread = thread_info::current_thread(); let name = thread.as_ref().and_then(|t| t.name()).unwrap_or(""); - let write = |err: &mut dyn crate::io::Write| { + let write = |err: &mut dyn crate::io::Write, backtrace: Option| { let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}"); static FIRST_PANIC: AtomicBool = AtomicBool::new(true); @@ -270,10 +279,19 @@ fn default_hook(info: &PanicInfo<'_>) { } Some(BacktraceStyle::Off) => { if FIRST_PANIC.swap(false, Ordering::SeqCst) { - let _ = writeln!( - err, - "note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace" - ); + if let Some(path) = path { + let _ = writeln!( + err, + "note: a backtrace for this error was stored at `{}`", + path.display(), + ); + } else { + let _ = writeln!( + err, + "note: run with `RUST_BACKTRACE=1` environment variable to display a \ + backtrace" + ); + } } } // If backtraces aren't supported, do nothing. @@ -281,11 +299,17 @@ fn default_hook(info: &PanicInfo<'_>) { } }; + if let Some(path) = path + && let Ok(mut out) = crate::fs::File::options().create(true).write(true).open(&path) + { + write(&mut out, BacktraceStyle::full()); + } + if let Some(local) = set_output_capture(None) { - write(&mut *local.lock().unwrap_or_else(|e| e.into_inner())); + write(&mut *local.lock().unwrap_or_else(|e| e.into_inner()), backtrace); set_output_capture(Some(local)); } else if let Some(mut out) = panic_output() { - write(&mut out); + write(&mut out, backtrace); } } diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 8f3201b0091d..f9cb755b01a3 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -558,6 +558,14 @@ impl Command { /// but this has some implementation limitations on Windows /// (see issue #37519). /// + /// # Platform-specific behavior + /// + /// Note on Windows: For executable files with the .exe extension, + /// it can be omitted when specifying the program for this Command. + /// However, if the file has a different extension, + /// a filename including the extension needs to be provided, + /// otherwise the file won't be found. + /// /// # Examples /// /// Basic usage: diff --git a/library/std/src/sync/mpmc/utils.rs b/library/std/src/sync/mpmc/utils.rs index d053d69e26ee..0cbc61160f7e 100644 --- a/library/std/src/sync/mpmc/utils.rs +++ b/library/std/src/sync/mpmc/utils.rs @@ -35,7 +35,9 @@ use crate::ops::{Deref, DerefMut}; any( target_arch = "arm", target_arch = "mips", + target_arch = "mips32r6", target_arch = "mips64", + target_arch = "mips64r6", target_arch = "riscv64", ), repr(align(32)) @@ -59,7 +61,9 @@ use crate::ops::{Deref, DerefMut}; target_arch = "powerpc64", target_arch = "arm", target_arch = "mips", + target_arch = "mips32r6", target_arch = "mips64", + target_arch = "mips64r6", target_arch = "riscv64", target_arch = "s390x", )), diff --git a/library/std/src/sys/common/alloc.rs b/library/std/src/sys/common/alloc.rs index a5fcbdf39c6c..3ccea3ce0e3e 100644 --- a/library/std/src/sys/common/alloc.rs +++ b/library/std/src/sys/common/alloc.rs @@ -9,6 +9,7 @@ use crate::ptr; target_arch = "arm", target_arch = "m68k", target_arch = "mips", + target_arch = "mips32r6", target_arch = "powerpc", target_arch = "powerpc64", target_arch = "sparc", @@ -24,6 +25,7 @@ pub const MIN_ALIGN: usize = 8; target_arch = "aarch64", target_arch = "loongarch64", target_arch = "mips64", + target_arch = "mips64r6", target_arch = "s390x", target_arch = "sparc64", target_arch = "riscv64", diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs index 6552d96ca699..dc9636ac8c93 100644 --- a/library/std/src/sys/personality/gcc.rs +++ b/library/std/src/sys/personality/gcc.rs @@ -59,7 +59,12 @@ const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1 / X0, X1 #[cfg(target_arch = "m68k")] const UNWIND_DATA_REG: (i32, i32) = (0, 1); // D0, D1 -#[cfg(any(target_arch = "mips", target_arch = "mips64"))] +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] const UNWIND_DATA_REG: (i32, i32) = (4, 5); // A0, A1 #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index ec24e137572d..521da6c4589b 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -51,10 +51,10 @@ pub const unwinder_private_data_size: usize = 5; #[cfg(target_arch = "m68k")] pub const unwinder_private_data_size: usize = 2; -#[cfg(target_arch = "mips")] +#[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] pub const unwinder_private_data_size: usize = 2; -#[cfg(target_arch = "mips64")] +#[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))] pub const unwinder_private_data_size: usize = 2; #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 766c187e8e83..32eb4e68b08d 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1629,6 +1629,7 @@ impl<'a> Builder<'a> { // fun to pass a flag to a tool to pass a flag to pass a flag to a tool // to change a flag in a binary? if self.config.rpath_enabled(target) && util::use_host_linker(target) { + let libdir = self.sysroot_libdir_relative(compiler).to_str().unwrap(); let rpath = if target.contains("apple") { // Note that we need to take one extra step on macOS to also pass // `-Wl,-instal_name,@rpath/...` to get things to work right. To @@ -1636,10 +1637,10 @@ impl<'a> Builder<'a> { // so. Note that this is definitely a hack, and we should likely // flesh out rpath support more fully in the future. rustflags.arg("-Zosx-rpath-install-name"); - Some("-Wl,-rpath,@loader_path/../lib") + Some(format!("-Wl,-rpath,@loader_path/../{}", libdir)) } else if !target.contains("windows") && !target.contains("aix") { rustflags.arg("-Clink-args=-Wl,-z,origin"); - Some("-Wl,-rpath,$ORIGIN/../lib") + Some(format!("-Wl,-rpath,$ORIGIN/../{}", libdir)) } else { None }; diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index de43a4019262..059eb9ffc7bc 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -133,7 +133,12 @@ const EXTRA_CHECK_CFGS: &[(Option, &'static str, Option<&[&'static str]>)] /* Extra values not defined in the built-in targets yet, but used in std */ (Some(Mode::Std), "target_env", Some(&["libnx"])), // (Some(Mode::Std), "target_os", Some(&[])), - (Some(Mode::Std), "target_arch", Some(&["asmjs", "spirv", "nvptx", "xtensa"])), + // #[cfg(bootstrap)] mips32r6, mips64r6 + ( + Some(Mode::Std), + "target_arch", + Some(&["asmjs", "spirv", "nvptx", "xtensa", "mips32r6", "mips64r6"]), + ), /* Extra names used by dependencies */ // FIXME: Used by serde_json, but we should not be triggering on external dependencies. (Some(Mode::Rustc), "no_btreemap_remove_entry", None), diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py index 5ab1874e9ed4..2e0f832192fd 100755 --- a/src/etc/htmldocck.py +++ b/src/etc/htmldocck.py @@ -274,6 +274,8 @@ def get_commands(template): args = shlex.split(args) except UnicodeEncodeError: args = [arg.decode('utf-8') for arg in shlex.split(args.encode('utf-8'))] + except Exception as exc: + raise Exception("line {}: {}".format(lineno + 1, exc)) from None yield Command(negated=negated, cmd=cmd, args=args, lineno=lineno+1, context=line) diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 5177cffe6bae..83886dd42aac 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -520,7 +520,9 @@ impl<'a> fmt::Display for Display<'a> { "loongarch64" => "LoongArch LA64", "m68k" => "M68k", "mips" => "MIPS", + "mips32r6" => "MIPS Release 6", "mips64" => "MIPS-64", + "mips64r6" => "MIPS-64 Release 6", "msp430" => "MSP430", "powerpc" => "PowerPC", "powerpc64" => "PowerPC-64", diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c4596140fb69..d14953f1bb78 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -90,6 +90,19 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< } v })); + items.extend(doc.inlined_foreigns.iter().flat_map(|((_, renamed), (res, local_import_id))| { + let Some(def_id) = res.opt_def_id() else { return Vec::new() }; + let name = renamed.unwrap_or_else(|| cx.tcx.item_name(def_id)); + let import = cx.tcx.hir().expect_item(*local_import_id); + match import.kind { + hir::ItemKind::Use(path, kind) => { + let hir::UsePath { segments, span, .. } = *path; + let path = hir::Path { segments, res: *res, span }; + clean_use_statement_inner(import, name, &path, kind, cx, &mut Default::default()) + } + _ => unreachable!(), + } + })); items.extend(doc.items.values().flat_map(|(item, renamed, _)| { // Now we actually lower the imports, skipping everything else. if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind { @@ -441,7 +454,7 @@ fn clean_projection<'tcx>( let bounds = cx .tcx .explicit_item_bounds(ty.skip_binder().def_id) - .arg_iter_copied(cx.tcx, ty.skip_binder().args) + .iter_instantiated_copied(cx.tcx, ty.skip_binder().args) .map(|(pred, _)| pred) .collect::>(); return clean_middle_opaque_bounds(cx, bounds); @@ -2071,7 +2084,7 @@ pub(crate) fn clean_middle_ty<'tcx>( let bounds = cx .tcx .explicit_item_bounds(def_id) - .arg_iter_copied(cx.tcx, args) + .iter_instantiated_copied(cx.tcx, args) .map(|(bound, _)| bound) .collect::>(); let ty = clean_middle_opaque_bounds(cx, bounds); @@ -2652,9 +2665,6 @@ fn clean_use_statement<'tcx>( let mut items = Vec::new(); let hir::UsePath { segments, ref res, span } = *path; for &res in res { - if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res { - continue; - } let path = hir::Path { segments, res, span }; items.append(&mut clean_use_statement_inner(import, name, &path, kind, cx, inlined_names)); } @@ -2669,6 +2679,9 @@ fn clean_use_statement_inner<'tcx>( cx: &mut DocContext<'tcx>, inlined_names: &mut FxHashSet<(ItemType, Symbol)>, ) -> Vec { + if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = path.res { + return Vec::new(); + } // We need this comparison because some imports (for std types for example) // are "inserted" as well but directly by the compiler and they should not be // taken into account. diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 82a1fe310b38..7fb069d6e707 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -176,6 +176,7 @@ pub(crate) fn new_handler( rustc_errors::Handler::with_emitter_and_flags( emitter, unstable_opts.diagnostic_handler_flags(true), + None, ) } @@ -296,6 +297,7 @@ pub(crate) fn create_config( }), make_codegen_backend: None, registry: rustc_driver::diagnostics_registry(), + ice_file: None, } } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 6047cf23350c..6766dcba18af 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -108,6 +108,7 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> { override_queries: None, make_codegen_backend: None, registry: rustc_driver::diagnostics_registry(), + ice_file: None, }; let test_args = options.test_args.clone(); @@ -586,7 +587,7 @@ pub(crate) fn make_test( ); // FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser - let handler = Handler::with_emitter(false, None, Box::new(emitter)); + let handler = Handler::with_emitter(false, None, Box::new(emitter), None); let sess = ParseSess::with_span_handler(handler, sm); let mut found_main = false; @@ -773,7 +774,7 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool { TerminalUrl::No, ); - let handler = Handler::with_emitter(false, None, Box::new(emitter)); + let handler = Handler::with_emitter(false, None, Box::new(emitter), None); let sess = ParseSess::with_span_handler(handler, sm); let mut parser = match maybe_new_parser_from_source_str(&sess, filename, source.to_owned()) { diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 9209915895aa..94e778406f8b 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -888,7 +888,7 @@ so that we can apply CSS-filters to change the arrow color in themes */ justify-content: start; flex: 3; } -.search-results .result-name span.alias { +.search-results .result-name .alias { color: var(--search-results-alias-color); } .search-results .result-name .grey { @@ -904,6 +904,9 @@ so that we can apply CSS-filters to change the arrow color in themes */ max-width: calc(100% - var(--search-typename-width)); display: inline-block; } +.search-results .result-name .path > * { + display: inline; +} .popover { position: absolute; diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 51d8e81ca868..42088e735544 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2108,30 +2108,23 @@ function initSearch(rawSearchIndex) { const resultName = document.createElement("div"); resultName.className = "result-name"; - if (item.is_alias) { - const alias = document.createElement("span"); - alias.className = "alias"; - - const bold = document.createElement("b"); - bold.innerText = item.alias; - alias.appendChild(bold); - - alias.insertAdjacentHTML( - "beforeend", - " - see "); - - resultName.appendChild(alias); - } - resultName.insertAdjacentHTML( "beforeend", - `\ -${typeName}\ -
\ - ${item.displayPath}${name}\ -
`); + `${typeName}`); link.appendChild(resultName); + let alias = " "; + if (item.is_alias) { + alias = `
\ +${item.alias} - see \ +
`; + } + resultName.insertAdjacentHTML( + "beforeend", + `
${alias}\ +${item.displayPath}${name}\ +
`); + const description = document.createElement("div"); description.className = "desc"; description.insertAdjacentHTML("beforeend", item.desc); diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index 369a8069593d..c82f2bc987aa 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -40,7 +40,7 @@ fn check_rust_syntax( let emitter = BufferEmitter { buffer: Lrc::clone(&buffer), fallback_bundle }; let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let handler = Handler::with_emitter(false, None, Box::new(emitter)); + let handler = Handler::with_emitter(false, None, Box::new(emitter), None); let source = dox[code_block.code].to_owned(); let sess = ParseSess::with_span_handler(handler, sm); diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 265123ddf6c8..66737a015215 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -35,6 +35,8 @@ pub(crate) struct Module<'hir> { (LocalDefId, Option), (&'hir hir::Item<'hir>, Option, Option), >, + /// Same as for `items`. + pub(crate) inlined_foreigns: FxIndexMap<(DefId, Option), (Res, LocalDefId)>, pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option)>, } @@ -54,6 +56,7 @@ impl Module<'_> { import_id, mods: Vec::new(), items: FxIndexMap::default(), + inlined_foreigns: FxIndexMap::default(), foreigns: Vec::new(), } } @@ -272,21 +275,30 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { return false; } - // For cross-crate impl inlining we need to know whether items are - // reachable in documentation -- a previously unreachable item can be - // made reachable by cross-crate inlining which we're checking here. - // (this is done here because we need to know this upfront). - if !ori_res_did.is_local() && !is_no_inline { - crate::visit_lib::lib_embargo_visit_item(self.cx, ori_res_did); - return false; - } - + let is_hidden = !document_hidden && tcx.is_doc_hidden(ori_res_did); let Some(res_did) = ori_res_did.as_local() else { - return false; + // For cross-crate impl inlining we need to know whether items are + // reachable in documentation -- a previously unreachable item can be + // made reachable by cross-crate inlining which we're checking here. + // (this is done here because we need to know this upfront). + crate::visit_lib::lib_embargo_visit_item(self.cx, ori_res_did); + if is_hidden { + return false; + } + // We store inlined foreign items otherwise, it'd mean that the `use` item would be kept + // around. It's not a problem unless this `use` imports both a local AND a foreign item. + // If a local item is inlined, its `use` is not supposed to still be around in `clean`, + // which would make appear the `use` in the generated documentation like the local item + // was not inlined even though it actually was. + self.modules + .last_mut() + .unwrap() + .inlined_foreigns + .insert((ori_res_did, renamed), (res, def_id)); + return true; }; let is_private = !self.cx.cache.effective_visibilities.is_directly_public(tcx, ori_res_did); - let is_hidden = !document_hidden && tcx.is_doc_hidden(ori_res_did); let item = tcx.hir().get_by_def_id(res_did); if !please_inline { @@ -314,7 +326,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { return false; } - let inlined = match tcx.hir().get_by_def_id(res_did) { + let inlined = match item { // Bang macros are handled a bit on their because of how they are handled by the // compiler. If they have `#[doc(hidden)]` and the re-export doesn't have // `#[doc(inline)]`, then we don't inline it. @@ -346,7 +358,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { }; self.view_item_stack.remove(&res_did); if inlined { - self.cx.cache.inlined_items.insert(res_did.to_def_id()); + self.cx.cache.inlined_items.insert(ori_res_did); } inlined } @@ -483,7 +495,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { continue; } } - self.add_to_current_mod(item, renamed, import_id); } } diff --git a/src/tools/cargo b/src/tools/cargo index 694a579566a9..1b15556767f4 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 694a579566a9a1482b20aff8a68f0e4edd99bd28 +Subproject commit 1b15556767f4b78a64e868eedf4073c423f02b93 diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs index e5f39d102cd3..8879c529262b 100644 --- a/src/tools/clippy/clippy_lints/src/doc.rs +++ b/src/tools/clippy/clippy_lints/src/doc.rs @@ -729,7 +729,7 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) { false, TerminalUrl::No, ); - let handler = Handler::with_emitter(false, None, Box::new(emitter)); + let handler = Handler::with_emitter(false, None, Box::new(emitter), None); let sess = ParseSess::with_span_handler(handler, sm); let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code) { diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index e54429aee8e8..621415c881cf 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { if let ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) = *ret_ty.kind() { let preds = cx.tcx.explicit_item_bounds(def_id); let mut is_future = false; - for (p, _span) in preds.arg_iter_copied(cx.tcx, args) { + for (p, _span) in preds.iter_instantiated_copied(cx.tcx, args) { if let Some(trait_pred) = p.as_trait_clause() { if Some(trait_pred.skip_binder().trait_ref.def_id) == cx.tcx.lang_items().future_trait() { is_future = true; diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index ad79143f4da9..fd39a246f48d 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -663,7 +663,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option sig_from_bounds( cx, ty, - cx.tcx.item_bounds(def_id).arg_iter(cx.tcx, args), + cx.tcx.item_bounds(def_id).iter_instantiated(cx.tcx, args), cx.tcx.opt_parent(def_id), ), ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)), @@ -739,7 +739,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option let mut output = None; let lang_items = cx.tcx.lang_items(); - for (pred, _) in cx.tcx.explicit_item_bounds(ty.def_id).arg_iter_copied(cx.tcx, ty.args) { + for (pred, _) in cx.tcx.explicit_item_bounds(ty.def_id).iter_instantiated_copied(cx.tcx, ty.args) { match pred.kind().skip_binder() { ty::ClauseKind::Trait(p) if (lang_items.fn_trait() == Some(p.def_id()) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index d67e9aaaa6e0..4ae2249097f6 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -232,7 +232,7 @@ impl TestProps { aux_builds: vec![], aux_crates: vec![], revisions: vec![], - rustc_env: vec![], + rustc_env: vec![("RUSTC_ICE".to_string(), "0".to_string())], unset_rustc_env: vec![], exec_env: vec![], unset_exec_env: vec![], diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index b91e1b09330e..7eeb987063fc 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -4149,8 +4149,8 @@ impl<'test> TestCx<'test> { # Match paths that don't include spaces. (?:\\[\pL\pN\.\-_']+)+\.\pL+ | - # If the path starts with a well-known root, then allow spaces. - \$(?:DIR|SRC_DIR|TEST_BUILD_DIR|BUILD_DIR|LIB_DIR)(?:\\[\pL\pN\.\-_' ]+)+ + # If the path starts with a well-known root, then allow spaces and no file extension. + \$(?:DIR|SRC_DIR|TEST_BUILD_DIR|BUILD_DIR|LIB_DIR)(?:\\[\pL\pN\.\-_'\ ]+)+ )"#, ) .unwrap() diff --git a/src/tools/compiletest/src/runtest/tests.rs b/src/tools/compiletest/src/runtest/tests.rs index 51105111175a..fb3dd326a4c8 100644 --- a/src/tools/compiletest/src/runtest/tests.rs +++ b/src/tools/compiletest/src/runtest/tests.rs @@ -8,8 +8,8 @@ fn normalize_platform_differences() { "$BUILD_DIR/../parser.rs" ); assert_eq!( - TestCx::normalize_platform_differences(r"$DIR\bar.rs hello\nworld"), - r"$DIR/bar.rs hello\nworld" + TestCx::normalize_platform_differences(r"$DIR\bar.rs: hello\nworld"), + r"$DIR/bar.rs: hello\nworld" ); assert_eq!( TestCx::normalize_platform_differences(r"either bar\baz.rs or bar\baz\mod.rs"), @@ -27,8 +27,8 @@ fn normalize_platform_differences() { ); assert_eq!(TestCx::normalize_platform_differences(r"$DIR\foo.rs:12:11"), "$DIR/foo.rs:12:11",); assert_eq!( - TestCx::normalize_platform_differences(r"$DIR\path with spaces 'n' quotes"), - "$DIR/path with spaces 'n' quotes", + TestCx::normalize_platform_differences(r"$DIR\path with\spaces 'n' quotes"), + "$DIR/path with/spaces 'n' quotes", ); assert_eq!( TestCx::normalize_platform_differences(r"$DIR\file_with\no_extension"), diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 6915c396d616..72a4adba8d41 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -45,8 +45,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // List taken from `library/std/src/sys/common/alloc.rs`. // This list should be kept in sync with the one from libstd. let min_align = match this.tcx.sess.target.arch.as_ref() { - "x86" | "arm" | "mips" | "powerpc" | "powerpc64" | "asmjs" | "wasm32" => 8, - "x86_64" | "aarch64" | "mips64" | "s390x" | "sparc64" | "loongarch64" => 16, + "x86" | "arm" | "mips" | "mips32r6" | "powerpc" | "powerpc64" | "asmjs" | "wasm32" => 8, + "x86_64" | "aarch64" | "mips64" | "mips64r6" | "s390x" | "sparc64" | "loongarch64" => + 16, arch => bug!("unsupported target architecture for malloc: `{}`", arch), }; // Windows always aligns, even small allocations. diff --git a/src/tools/miri/tests/fail/layout_cycle.stderr b/src/tools/miri/tests/fail/layout_cycle.stderr index 62b7d5fb77d1..38907a1c50cc 100644 --- a/src/tools/miri/tests/fail/layout_cycle.stderr +++ b/src/tools/miri/tests/fail/layout_cycle.stderr @@ -2,6 +2,7 @@ error[E0391]: cycle detected when computing layout of `S>` | = note: ...which requires computing layout of ` as Tr>::I`... = note: ...which again requires computing layout of `S>`, completing the cycle + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: post-monomorphization error: a cycle occurred during layout computation --> RUSTLIB/core/src/mem/mod.rs:LL:CC diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs index 81b5015dde33..92d2425cd3b9 100644 --- a/src/tools/rustfmt/src/parse/session.rs +++ b/src/tools/rustfmt/src/parse/session.rs @@ -162,6 +162,7 @@ fn default_handler( ignore_path_set, can_reset, }), + None, ) } @@ -233,7 +234,7 @@ impl ParseSess { } pub(crate) fn set_silent_emitter(&mut self) { - self.parse_sess.span_diagnostic = Handler::with_emitter(true, None, silent_emitter()); + self.parse_sess.span_diagnostic = Handler::with_emitter(true, None, silent_emitter(), None); } pub(crate) fn span_to_filename(&self, span: Span) -> FileName { diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 9f0f0d86c8b2..2be369d2b740 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -253,6 +253,9 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "thiserror-impl", "thorin-dwp", "thread_local", + "time", + "time-core", + "time-macros", "tinystr", "tinyvec", "tinyvec_macros", diff --git a/tests/codegen/no_builtins-at-crate.rs b/tests/codegen/no_builtins-at-crate.rs new file mode 100644 index 000000000000..02ed670900ed --- /dev/null +++ b/tests/codegen/no_builtins-at-crate.rs @@ -0,0 +1,24 @@ +// compile-flags: -C opt-level=1 + +#![no_builtins] +#![crate_type = "lib"] + +// CHECK: define +// CHECK-SAME: @__aeabi_memcpy +// CHECK-SAME: #0 +#[no_mangle] +pub unsafe extern "C" fn __aeabi_memcpy(dest: *mut u8, src: *const u8, size: usize) { + // CHECK: call + // CHECK-SAME: @memcpy( + memcpy(dest, src, size); +} + +// CHECK: declare +// CHECK-SAME: @memcpy +// CHECK-SAME: #0 +extern "C" { + pub fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8; +} + +// CHECK: attributes #0 +// CHECK-SAME: "no-builtins" diff --git a/tests/run-make-fulldeps/issue-19371/foo.rs b/tests/run-make-fulldeps/issue-19371/foo.rs index d4959247d1cd..681326387591 100644 --- a/tests/run-make-fulldeps/issue-19371/foo.rs +++ b/tests/run-make-fulldeps/issue-19371/foo.rs @@ -52,6 +52,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) { input, output_file: Some(OutFileName::Real(output)), output_dir: None, + ice_file: None, file_loader: None, locale_resources: &[], lint_caps: Default::default(), diff --git a/tests/run-make/dump-ice-to-disk/Makefile b/tests/run-make/dump-ice-to-disk/Makefile new file mode 100644 index 000000000000..4f33d590237b --- /dev/null +++ b/tests/run-make/dump-ice-to-disk/Makefile @@ -0,0 +1,9 @@ +include ../tools.mk + +# ignore-windows + +export RUSTC := $(RUSTC_ORIGINAL) +export TMPDIR := $(TMPDIR) + +all: + bash check.sh diff --git a/tests/run-make/dump-ice-to-disk/check.sh b/tests/run-make/dump-ice-to-disk/check.sh new file mode 100644 index 000000000000..91109596a451 --- /dev/null +++ b/tests/run-make/dump-ice-to-disk/check.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +# Default nightly behavior (write ICE to current directory) +# FIXME(estebank): these are failing on CI, but passing locally. +# $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-default.log 2>&1 +# default=$(cat ./rustc-ice-*.txt | wc -l) +# rm ./rustc-ice-*.txt + +# Explicit directory set +export RUSTC_ICE=$TMPDIR +$RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-default-set.log 2>&1 +default_set=$(cat $TMPDIR/rustc-ice-*.txt | wc -l) +content=$(cat $TMPDIR/rustc-ice-*.txt) +rm $TMPDIR/rustc-ice-*.txt +RUST_BACKTRACE=short $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-short.log 2>&1 +short=$(cat $TMPDIR/rustc-ice-*.txt | wc -l) +rm $TMPDIR/rustc-ice-*.txt +RUST_BACKTRACE=full $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-full.log 2>&1 +full=$(cat $TMPDIR/rustc-ice-*.txt | wc -l) +rm $TMPDIR/rustc-ice-*.txt + +# Explicitly disabling ICE dump +export RUSTC_ICE=0 +$RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-disabled.log 2>&1 +should_be_empty_tmp=$(ls -l $TMPDIR/rustc-ice-*.txt | wc -l) +should_be_empty_dot=$(ls -l ./rustc-ice-*.txt | wc -l) + +echo "#### ICE Dump content:" +echo $content +echo "#### default length:" +echo $default +echo "#### short length:" +echo $short +echo "#### default_set length:" +echo $default_set +echo "#### full length:" +echo $full +echo "#### should_be_empty_dot length:" +echo $should_be_empty_dot +echo "#### should_be_empty_tmp length:" +echo $should_be_empty_tmp + +## Verify that a the ICE dump file is created in the appropriate directories, that +## their lengths are the same regardless of other backtrace configuration options, +## that the file is not created when asked to (RUSTC_ICE=0) and that the file +## contains at least part of the expected content. +if [ $short -eq $default_set ] && + #[ $default -eq $short ] && + [ $default_set -eq $full ] && + [[ $content == *"thread 'rustc' panicked at "* ]] && + [[ $content == *"stack backtrace:"* ]] && + #[ $default -gt 0 ] && + [ $should_be_empty_dot -eq 0 ] && + [ $should_be_empty_tmp -eq 0 ]; then + exit 0 +else + exit 1 +fi diff --git a/tests/run-make/dump-ice-to-disk/src/lib.rs b/tests/run-make/dump-ice-to-disk/src/lib.rs new file mode 100644 index 000000000000..b23b7f830d73 --- /dev/null +++ b/tests/run-make/dump-ice-to-disk/src/lib.rs @@ -0,0 +1,7 @@ +fn func(s: &str) { + println!("{}", s); +} + +fn main() { + func(1); +} diff --git a/tests/run-make/exit-code/Makefile b/tests/run-make/exit-code/Makefile index 6458b71688ff..155e5cd11234 100644 --- a/tests/run-make/exit-code/Makefile +++ b/tests/run-make/exit-code/Makefile @@ -5,7 +5,7 @@ all: $(RUSTC) success.rs; [ $$? -eq 0 ] $(RUSTC) --invalid-arg-foo; [ $$? -eq 1 ] $(RUSTC) compile-error.rs; [ $$? -eq 1 ] - $(RUSTC) -Ztreat-err-as-bug compile-error.rs; [ $$? -eq 101 ] + RUSTC_ICE=0 $(RUSTC) -Ztreat-err-as-bug compile-error.rs; [ $$? -eq 101 ] $(RUSTDOC) -o $(TMPDIR)/exit-code success.rs; [ $$? -eq 0 ] $(RUSTDOC) --invalid-arg-foo; [ $$? -eq 1 ] $(RUSTDOC) compile-error.rs; [ $$? -eq 1 ] diff --git a/tests/run-make/no-builtins-attribute/Makefile b/tests/run-make/no-builtins-attribute/Makefile new file mode 100644 index 000000000000..0ce95facaea4 --- /dev/null +++ b/tests/run-make/no-builtins-attribute/Makefile @@ -0,0 +1,9 @@ +include ../tools.mk + +# We want to check if `no-builtins` is also added to the function declarations in the used crate. + +all: + $(RUSTC) no_builtins.rs --emit=link + $(RUSTC) main.rs --emit=llvm-ir + + cat "$(TMPDIR)"/main.ll | "$(LLVM_FILECHECK)" filecheck.main.txt diff --git a/tests/run-make/no-builtins-attribute/filecheck.main.txt b/tests/run-make/no-builtins-attribute/filecheck.main.txt new file mode 100644 index 000000000000..ecd650bdca80 --- /dev/null +++ b/tests/run-make/no-builtins-attribute/filecheck.main.txt @@ -0,0 +1,5 @@ +CHECK: declare void @foo() +CHECK-SAME: #[[ATTR_3:[0-9]+]] + +CHECK: attributes #[[ATTR_3]] +CHECK-SAME: no-builtins diff --git a/tests/run-make/no-builtins-attribute/main.rs b/tests/run-make/no-builtins-attribute/main.rs new file mode 100644 index 000000000000..77754b37e318 --- /dev/null +++ b/tests/run-make/no-builtins-attribute/main.rs @@ -0,0 +1,10 @@ +extern crate no_builtins; + +#[no_mangle] +fn call_foo() { + no_builtins::foo(); +} + +fn main() { + call_foo(); +} diff --git a/tests/run-make/no-builtins-attribute/no_builtins.rs b/tests/run-make/no-builtins-attribute/no_builtins.rs new file mode 100644 index 000000000000..8ca862d2f777 --- /dev/null +++ b/tests/run-make/no-builtins-attribute/no_builtins.rs @@ -0,0 +1,5 @@ +#![crate_type = "lib"] +#![no_builtins] + +#[no_mangle] +pub fn foo() {} diff --git a/tests/run-make/short-ice/check.sh b/tests/run-make/short-ice/check.sh index a13b7eeca8f3..56babd2142f8 100644 --- a/tests/run-make/short-ice/check.sh +++ b/tests/run-make/short-ice/check.sh @@ -1,5 +1,5 @@ #!/bin/sh - +export RUSTC_ICE=0 RUST_BACKTRACE=1 $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-1.log 2>&1 RUST_BACKTRACE=full $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-2.log 2>&1 diff --git a/tests/rustdoc-gui/search-reexport.goml b/tests/rustdoc-gui/search-reexport.goml index 6ea6d53e2875..b9d2c8f15cee 100644 --- a/tests/rustdoc-gui/search-reexport.goml +++ b/tests/rustdoc-gui/search-reexport.goml @@ -26,7 +26,7 @@ write: (".search-input", "AliasForTheStdReexport") wait-for: "//a[@class='result-import']" assert-text: ( "a.result-import .result-name", - "AliasForTheStdReexport - see re-export test_docs::TheStdReexport", + "re-export AliasForTheStdReexport - see test_docs::TheStdReexport", ) // Same thing again, we click on it to ensure the background is once again set as expected. click: "//a[@class='result-import']" diff --git a/tests/rustdoc-gui/search-result-color.goml b/tests/rustdoc-gui/search-result-color.goml index 7a7785fd9ac3..f9f81c5ba04e 100644 --- a/tests/rustdoc-gui/search-result-color.goml +++ b/tests/rustdoc-gui/search-result-color.goml @@ -368,8 +368,8 @@ define-function: ( // Waiting for the search results to appear... wait-for: "#search-tabs" // Checking that the colors for the alias element are the ones expected. - assert-css: (".result-name > .alias", {"color": |alias|}) - assert-css: (".result-name > .alias > .grey", {"color": |grey|}) + assert-css: (".result-name .path .alias", {"color": |alias|}) + assert-css: (".result-name .path .alias > .grey", {"color": |grey|}) // Leave the search results to prevent reloading with an already filled search input. press-key: "Escape" }, diff --git a/tests/rustdoc-ui/ice-bug-report-url.rs b/tests/rustdoc-ui/ice-bug-report-url.rs index 8ede91cf8f4f..7689d78d31f3 100644 --- a/tests/rustdoc-ui/ice-bug-report-url.rs +++ b/tests/rustdoc-ui/ice-bug-report-url.rs @@ -1,4 +1,5 @@ // compile-flags: -Ztreat-err-as-bug +// rustc-env:RUSTC_ICE=0 // failure-status: 101 // error-pattern: aborting due to // error-pattern: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md diff --git a/tests/rustdoc-ui/ice-bug-report-url.stderr b/tests/rustdoc-ui/ice-bug-report-url.stderr index 98c08b9a8944..7d9f05f8f4ed 100644 --- a/tests/rustdoc-ui/ice-bug-report-url.stderr +++ b/tests/rustdoc-ui/ice-bug-report-url.stderr @@ -1,5 +1,5 @@ error: expected one of `->`, `where`, or `{`, found `` - --> $DIR/ice-bug-report-url.rs:13:10 + --> $DIR/ice-bug-report-url.rs:14:10 | LL | fn wrong() | ^ expected one of `->`, `where`, or `{` diff --git a/tests/rustdoc-ui/issue-110629-private-type-cycle-dyn.stderr b/tests/rustdoc-ui/issue-110629-private-type-cycle-dyn.stderr index 79e1b753112b..9aeb3389e2d3 100644 --- a/tests/rustdoc-ui/issue-110629-private-type-cycle-dyn.stderr +++ b/tests/rustdoc-ui/issue-110629-private-type-cycle-dyn.stderr @@ -19,6 +19,7 @@ LL | | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { LL | | assert!(bar(&meh) == bar(&muh)); LL | | } | |_^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/rustdoc/display-hidden-items.rs b/tests/rustdoc/display-hidden-items.rs new file mode 100644 index 000000000000..d97d5b4a9688 --- /dev/null +++ b/tests/rustdoc/display-hidden-items.rs @@ -0,0 +1,71 @@ +// Test to ensure that the `--document-hidden-items` option is working as expected. +// compile-flags: -Z unstable-options --document-hidden-items +// ignore-tidy-linelength + +#![crate_name = "foo"] + +// @has 'foo/index.html' +// @has - '//*[@id="reexport.hidden_reexport"]/code' 'pub use hidden::inside_hidden as hidden_reexport;' +#[doc(hidden)] +pub use hidden::inside_hidden as hidden_reexport; + +// @has - '//*[@class="item-name"]/a[@class="trait"]' 'TraitHidden' +// @has 'foo/trait.TraitHidden.html' +#[doc(hidden)] +pub trait TraitHidden {} + +// @has 'foo/index.html' '//*[@class="item-name"]/a[@class="trait"]' 'Trait' +pub trait Trait { + // @has 'foo/trait.Trait.html' + // @has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' 'const BAR: u32 = 0u32' + #[doc(hidden)] + const BAR: u32 = 0; + + // @has - '//*[@id="method.foo"]/*[@class="code-header"]' 'fn foo()' + #[doc(hidden)] + fn foo() {} +} + +// @has 'foo/index.html' '//*[@class="item-name"]/a[@class="struct"]' 'Struct' +// @has 'foo/struct.Struct.html' +pub struct Struct { + // @has - '//*[@id="structfield.a"]/code' 'a: u32' + #[doc(hidden)] + pub a: u32, +} + +impl Struct { + // @has - '//*[@id="method.new"]/*[@class="code-header"]' 'pub fn new() -> Self' + #[doc(hidden)] + pub fn new() -> Self { Self { a: 0 } } +} + +impl Trait for Struct { + // @has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' 'const BAR: u32 = 0u32' + // @has - '//*[@id="method.foo"]/*[@class="code-header"]' 'fn foo()' +} +// @has - '//*[@id="impl-TraitHidden-for-Struct"]/*[@class="code-header"]' 'impl TraitHidden for Struct' +impl TraitHidden for Struct {} + +// @has 'foo/index.html' '//*[@class="item-name"]/a[@class="enum"]' 'HiddenEnum' +// @has 'foo/enum.HiddenEnum.html' +#[doc(hidden)] +pub enum HiddenEnum { + A, +} + +// @has 'foo/index.html' '//*[@class="item-name"]/a[@class="enum"]' 'Enum' +pub enum Enum { + // @has 'foo/enum.Enum.html' '//*[@id="variant.A"]/*[@class="code-header"]' 'A' + #[doc(hidden)] + A, +} + +// @has 'foo/index.html' '//*[@class="item-name"]/a[@class="mod"]' 'hidden' +#[doc(hidden)] +pub mod hidden { + // @has 'foo/hidden/index.html' + // @has - '//*[@class="item-name"]/a[@class="fn"]' 'inside_hidden' + // @has 'foo/hidden/fn.inside_hidden.html' + pub fn inside_hidden() {} +} diff --git a/tests/rustdoc/issue-105735-overlapping-reexport-2.rs b/tests/rustdoc/issue-105735-overlapping-reexport-2.rs new file mode 100644 index 000000000000..910824839489 --- /dev/null +++ b/tests/rustdoc/issue-105735-overlapping-reexport-2.rs @@ -0,0 +1,25 @@ +// Regression test to ensure that both `AtomicU8` items are displayed but not the re-export. + +#![crate_name = "foo"] +#![no_std] + +// @has 'foo/index.html' +// @has - '//*[@class="item-name"]/a[@class="type"]' 'AtomicU8' +// @has - '//*[@class="item-name"]/a[@class="constant"]' 'AtomicU8' +// We also ensure we don't have another item displayed. +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 2 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Type Definitions' +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants' + +mod other { + pub type AtomicU8 = (); +} + +mod thing { + pub use crate::other::AtomicU8; + + #[allow(non_upper_case_globals)] + pub const AtomicU8: () = (); +} + +pub use crate::thing::AtomicU8; diff --git a/tests/rustdoc/issue-105735-overlapping-reexport.rs b/tests/rustdoc/issue-105735-overlapping-reexport.rs new file mode 100644 index 000000000000..50f2450b90a0 --- /dev/null +++ b/tests/rustdoc/issue-105735-overlapping-reexport.rs @@ -0,0 +1,21 @@ +// Regression test to ensure that both `AtomicU8` items are displayed but not the re-export. + +#![crate_name = "foo"] +#![no_std] + +// @has 'foo/index.html' +// @has - '//*[@class="item-name"]/a[@class="struct"]' 'AtomicU8' +// @has - '//*[@class="item-name"]/a[@class="constant"]' 'AtomicU8' +// We also ensure we don't have another item displayed. +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 2 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants' + +mod thing { + pub use core::sync::atomic::AtomicU8; + + #[allow(non_upper_case_globals)] + pub const AtomicU8: () = (); +} + +pub use crate::thing::AtomicU8; diff --git a/tests/ui/associated-consts/defaults-cyclic-fail.stderr b/tests/ui/associated-consts/defaults-cyclic-fail.stderr index a1483911b297..ebdb76e4286a 100644 --- a/tests/ui/associated-consts/defaults-cyclic-fail.stderr +++ b/tests/ui/associated-consts/defaults-cyclic-fail.stderr @@ -15,6 +15,7 @@ note: cycle used when const-evaluating + checking `main::promoted[1]` | LL | assert_eq!(<() as Tr>::A, 0); | ^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr index be5781761517..51bf0cb5e5ce 100644 --- a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr +++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr @@ -26,6 +26,7 @@ LL | const BAR: u32 = IMPL_REF_BAR; | ^^^^^^^^^^^^^^ = note: ...which again requires elaborating drops for `::BAR`, completing the cycle = note: cycle used when running analysis passes on this crate + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr index 8347b260b562..8277d41a1c94 100644 --- a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr +++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr @@ -26,6 +26,7 @@ LL | const BAR: u32 = DEFAULT_REF_BAR; | ^^^^^^^^^^^^^^ = note: ...which again requires elaborating drops for `FooDefault::BAR`, completing the cycle = note: cycle used when running analysis passes on this crate + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr index 3955a3120c47..9983ba794cd2 100644 --- a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr +++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr @@ -26,6 +26,7 @@ LL | const BAR: u32 = TRAIT_REF_BAR; | ^^^^^^^^^^^^^^ = note: ...which again requires elaborating drops for `::BAR`, completing the cycle = note: cycle used when running analysis passes on this crate + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr index 23269e1afab5..3c373f139cbe 100644 --- a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr +++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr @@ -37,6 +37,7 @@ LL | | LL | | LL | | fn main() {} | |____________^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr index aaa9a39ea0f4..ab6a97b3d858 100644 --- a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr +++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr @@ -31,6 +31,7 @@ LL | | // FIXME(inherent_associated_types): This shouldn't lead to a cycle error LL | | LL | | fn main() {} | |____________^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/associated-type-bounds/ambiguous-associated-type2.rs b/tests/ui/associated-type-bounds/ambiguous-associated-type2.rs index 48de593342fa..e9cd57f17397 100644 --- a/tests/ui/associated-type-bounds/ambiguous-associated-type2.rs +++ b/tests/ui/associated-type-bounds/ambiguous-associated-type2.rs @@ -7,4 +7,6 @@ trait Bar { trait Baz: Foo + Bar {} //~^ ERROR cycle detected when computing the super traits of `Baz` with associated type name `Item` [E0391] + + fn main() {} diff --git a/tests/ui/associated-type-bounds/ambiguous-associated-type2.stderr b/tests/ui/associated-type-bounds/ambiguous-associated-type2.stderr index 575b00e09b02..f2604f0ba881 100644 --- a/tests/ui/associated-type-bounds/ambiguous-associated-type2.stderr +++ b/tests/ui/associated-type-bounds/ambiguous-associated-type2.stderr @@ -10,6 +10,7 @@ note: cycle used when computing the super predicates of `Baz` | LL | trait Baz: Foo + Bar {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/associated-types/issue-20825.stderr b/tests/ui/associated-types/issue-20825.stderr index c4dea68b884a..02b3536e2d15 100644 --- a/tests/ui/associated-types/issue-20825.stderr +++ b/tests/ui/associated-types/issue-20825.stderr @@ -10,6 +10,7 @@ note: cycle used when computing the super predicates of `Processor` | LL | pub trait Processor: Subscriber { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/check-cfg/compact-values.stderr b/tests/ui/check-cfg/compact-values.stderr index 70a967c0e5f6..5f8dbbdb05ce 100644 --- a/tests/ui/check-cfg/compact-values.stderr +++ b/tests/ui/check-cfg/compact-values.stderr @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition value LL | #[cfg(target(os = "linux", arch = "X"))] | ^^^^^^^^^^ | - = note: expected values for `target_arch` are: `aarch64`, `arm`, `avr`, `bpf`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips64`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64` + = note: expected values for `target_arch` are: `aarch64`, `arm`, `avr`, `bpf`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64` = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr b/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr index 7bd50649d6d0..684e528220f8 100644 --- a/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr +++ b/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr @@ -20,6 +20,7 @@ note: cycle used when coherence checking all impls of trait `Trait` | LL | trait Trait { type Assoc; } | ^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error; 1 warning emitted diff --git a/tests/ui/const-generics/generic_const_exprs/closures.stderr b/tests/ui/const-generics/generic_const_exprs/closures.stderr index a7d891d77908..45d7922bd0b8 100644 --- a/tests/ui/const-generics/generic_const_exprs/closures.stderr +++ b/tests/ui/const-generics/generic_const_exprs/closures.stderr @@ -20,6 +20,7 @@ note: cycle used when checking that `test` is well-formed | LL | fn test() -> [u8; N + (|| 42)()] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-83765.stderr b/tests/ui/const-generics/issues/issue-83765.stderr index d7b2b006c2ae..df734933c250 100644 --- a/tests/ui/const-generics/issues/issue-83765.stderr +++ b/tests/ui/const-generics/issues/issue-83765.stderr @@ -15,6 +15,7 @@ note: cycle used when computing candidate for `; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error[E0391]: cycle detected when computing type of `S` --> $DIR/issue-103790.rs:4:1 @@ -58,6 +59,7 @@ LL | | struct S; LL | | LL | | fn main() {} | |____________^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 4 previous errors diff --git a/tests/ui/consts/issue-36163.stderr b/tests/ui/consts/issue-36163.stderr index 7137c053847c..190b41062f81 100644 --- a/tests/ui/consts/issue-36163.stderr +++ b/tests/ui/consts/issue-36163.stderr @@ -15,6 +15,7 @@ note: cycle used when simplifying constant for the type system `Foo::B::{constan | LL | B = A, | ^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/consts/issue-44415.stderr b/tests/ui/consts/issue-44415.stderr index ec64b956dfe2..01d24a620814 100644 --- a/tests/ui/consts/issue-44415.stderr +++ b/tests/ui/consts/issue-44415.stderr @@ -23,6 +23,7 @@ note: cycle used when checking that `Foo` is well-formed | LL | struct Foo { | ^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/consts/recursive-zst-static.default.stderr b/tests/ui/consts/recursive-zst-static.default.stderr index d68960b09721..d592b5aeef5e 100644 --- a/tests/ui/consts/recursive-zst-static.default.stderr +++ b/tests/ui/consts/recursive-zst-static.default.stderr @@ -19,6 +19,7 @@ LL | | fn main() { LL | | FOO LL | | } | |_^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/consts/recursive-zst-static.unleash.stderr b/tests/ui/consts/recursive-zst-static.unleash.stderr index d68960b09721..d592b5aeef5e 100644 --- a/tests/ui/consts/recursive-zst-static.unleash.stderr +++ b/tests/ui/consts/recursive-zst-static.unleash.stderr @@ -19,6 +19,7 @@ LL | | fn main() { LL | | FOO LL | | } | |_^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/consts/write-to-static-mut-in-static.stderr b/tests/ui/consts/write-to-static-mut-in-static.stderr index 395b2d42f97a..5665e56439e0 100644 --- a/tests/ui/consts/write-to-static-mut-in-static.stderr +++ b/tests/ui/consts/write-to-static-mut-in-static.stderr @@ -27,6 +27,7 @@ LL | | LL | | LL | | fn main() {} | |____________^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 2 previous errors diff --git a/tests/ui/cycle-trait/cycle-trait-default-type-trait.stderr b/tests/ui/cycle-trait/cycle-trait-default-type-trait.stderr index 9d715f494714..3b66704d6131 100644 --- a/tests/ui/cycle-trait/cycle-trait-default-type-trait.stderr +++ b/tests/ui/cycle-trait/cycle-trait-default-type-trait.stderr @@ -14,6 +14,7 @@ LL | | } LL | | LL | | fn main() { } | |_____________^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/cycle-trait/cycle-trait-supertrait-direct.stderr b/tests/ui/cycle-trait/cycle-trait-supertrait-direct.stderr index e2b2aac05ac9..03cb5015ab0b 100644 --- a/tests/ui/cycle-trait/cycle-trait-supertrait-direct.stderr +++ b/tests/ui/cycle-trait/cycle-trait-supertrait-direct.stderr @@ -12,6 +12,7 @@ LL | / trait Chromosome: Chromosome { LL | | LL | | } | |_^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/cycle-trait/cycle-trait-supertrait-indirect.stderr b/tests/ui/cycle-trait/cycle-trait-supertrait-indirect.stderr index c903e1146576..c7cc31435204 100644 --- a/tests/ui/cycle-trait/cycle-trait-supertrait-indirect.stderr +++ b/tests/ui/cycle-trait/cycle-trait-supertrait-indirect.stderr @@ -15,6 +15,7 @@ note: cycle used when computing the super predicates of `A` | LL | trait A: B { | ^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/cycle-trait/issue-12511.stderr b/tests/ui/cycle-trait/issue-12511.stderr index 558aad10946e..f5e4f83473df 100644 --- a/tests/ui/cycle-trait/issue-12511.stderr +++ b/tests/ui/cycle-trait/issue-12511.stderr @@ -17,6 +17,7 @@ LL | / trait T1 : T2 { LL | | LL | | } | |_^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/dyn-star/param-env-region-infer.next.stderr b/tests/ui/dyn-star/param-env-region-infer.next.stderr index dd724a659082..28aec533a006 100644 --- a/tests/ui/dyn-star/param-env-region-infer.next.stderr +++ b/tests/ui/dyn-star/param-env-region-infer.next.stderr @@ -23,6 +23,7 @@ LL | | use std::fmt::Debug; LL | | LL | | fn main() {} | |____________^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/fmt/closing-brace-as-fill.rs b/tests/ui/fmt/closing-brace-as-fill.rs new file mode 100644 index 000000000000..6ad257f943e9 --- /dev/null +++ b/tests/ui/fmt/closing-brace-as-fill.rs @@ -0,0 +1,8 @@ +// issue: 112732 + +// `}` is typoed since it is interpreted as a fill character rather than a closing bracket + +fn main() { + println!("Hello, world! {0:}<3", 2); + //~^ ERROR invalid format string: expected `'}'` but string was terminated +} diff --git a/tests/ui/fmt/closing-brace-as-fill.stderr b/tests/ui/fmt/closing-brace-as-fill.stderr new file mode 100644 index 000000000000..aa1e5aff6525 --- /dev/null +++ b/tests/ui/fmt/closing-brace-as-fill.stderr @@ -0,0 +1,12 @@ +error: invalid format string: expected `'}'` but string was terminated + --> $DIR/closing-brace-as-fill.rs:6:35 + | +LL | println!("Hello, world! {0:}<3", 2); + | - ^ expected `'}'` in format string + | | + | this is not interpreted as a formatting closing brace + | + = note: the character `'}'` is interpreted as a fill character because of the `:` that precedes it + +error: aborting due to previous error + diff --git a/tests/ui/fmt/format-string-error-2.stderr b/tests/ui/fmt/format-string-error-2.stderr index 76cdfbb93bf2..dfd24bf60ad5 100644 --- a/tests/ui/fmt/format-string-error-2.stderr +++ b/tests/ui/fmt/format-string-error-2.stderr @@ -10,7 +10,7 @@ error: invalid format string: expected `'}'`, found `'a'` LL | format!("{ | - because of this opening brace LL | a"); - | ^ expected `}` in format string + | ^ expected `'}'` in format string | = note: if you intended to print `{`, you can escape it using `{{` @@ -21,7 +21,7 @@ LL | format!("{ \ | - because of this opening brace LL | \ LL | b"); - | ^ expected `}` in format string + | ^ expected `'}'` in format string | = note: if you intended to print `{`, you can escape it using `{{` @@ -29,7 +29,7 @@ error: invalid format string: expected `'}'`, found `'\'` --> $DIR/format-string-error-2.rs:11:18 | LL | format!(r#"{ \ - | - ^ expected `}` in format string + | - ^ expected `'}'` in format string | | | because of this opening brace | @@ -39,7 +39,7 @@ error: invalid format string: expected `'}'`, found `'\'` --> $DIR/format-string-error-2.rs:15:18 | LL | format!(r#"{ \n - | - ^ expected `}` in format string + | - ^ expected `'}'` in format string | | | because of this opening brace | @@ -52,7 +52,7 @@ LL | format!("{ \n | - because of this opening brace LL | \n LL | e"); - | ^ expected `}` in format string + | ^ expected `'}'` in format string | = note: if you intended to print `{`, you can escape it using `{{` @@ -62,7 +62,7 @@ error: invalid format string: expected `'}'`, found `'a'` LL | { | - because of this opening brace LL | a"); - | ^ expected `}` in format string + | ^ expected `'}'` in format string | = note: if you intended to print `{`, you can escape it using `{{` @@ -72,7 +72,7 @@ error: invalid format string: expected `'}'`, found `'a'` LL | { | - because of this opening brace LL | a - | ^ expected `}` in format string + | ^ expected `'}'` in format string | = note: if you intended to print `{`, you can escape it using `{{` @@ -83,7 +83,7 @@ LL | { \ | - because of this opening brace LL | \ LL | b"); - | ^ expected `}` in format string + | ^ expected `'}'` in format string | = note: if you intended to print `{`, you can escape it using `{{` @@ -94,7 +94,7 @@ LL | { \ | - because of this opening brace LL | \ LL | b \ - | ^ expected `}` in format string + | ^ expected `'}'` in format string | = note: if you intended to print `{`, you can escape it using `{{` @@ -102,7 +102,7 @@ error: invalid format string: expected `'}'`, found `'\'` --> $DIR/format-string-error-2.rs:45:8 | LL | raw { \ - | - ^ expected `}` in format string + | - ^ expected `'}'` in format string | | | because of this opening brace | @@ -112,7 +112,7 @@ error: invalid format string: expected `'}'`, found `'\'` --> $DIR/format-string-error-2.rs:50:8 | LL | raw { \n - | - ^ expected `}` in format string + | - ^ expected `'}'` in format string | | | because of this opening brace | @@ -125,7 +125,7 @@ LL | { \n | - because of this opening brace LL | \n LL | e"); - | ^ expected `}` in format string + | ^ expected `'}'` in format string | = note: if you intended to print `{`, you can escape it using `{{` @@ -135,7 +135,7 @@ error: invalid format string: expected `'}'`, found `'a'` LL | { | - because of this opening brace LL | asdf} - | ^ expected `}` in format string + | ^ expected `'}'` in format string | = note: if you intended to print `{`, you can escape it using `{{` diff --git a/tests/ui/fmt/format-string-error.stderr b/tests/ui/fmt/format-string-error.stderr index 8a32c225485f..37a181e6fcb2 100644 --- a/tests/ui/fmt/format-string-error.stderr +++ b/tests/ui/fmt/format-string-error.stderr @@ -62,7 +62,7 @@ error: invalid format string: expected `'}'`, found `'\'` --> $DIR/format-string-error.rs:19:23 | LL | let _ = format!("{\}"); - | -^ expected `}` in format string + | -^ expected `'}'` in format string | | | because of this opening brace | diff --git a/tests/ui/fmt/format-string-wrong-order.stderr b/tests/ui/fmt/format-string-wrong-order.stderr index 461af354a4e1..0a2e04026d97 100644 --- a/tests/ui/fmt/format-string-wrong-order.stderr +++ b/tests/ui/fmt/format-string-wrong-order.stderr @@ -26,7 +26,7 @@ error: invalid format string: expected `'}'`, found `'?'` --> $DIR/format-string-wrong-order.rs:9:15 | LL | format!("{??}", bar); - | -^ expected `}` in format string + | -^ expected `'}'` in format string | | | because of this opening brace | @@ -36,7 +36,7 @@ error: invalid format string: expected `'}'`, found `'?'` --> $DIR/format-string-wrong-order.rs:11:15 | LL | format!("{?;bar}"); - | -^ expected `}` in format string + | -^ expected `'}'` in format string | | | because of this opening brace | diff --git a/tests/ui/fmt/ifmt-bad-arg.stderr b/tests/ui/fmt/ifmt-bad-arg.stderr index ed008c454a31..09ce3dca4117 100644 --- a/tests/ui/fmt/ifmt-bad-arg.stderr +++ b/tests/ui/fmt/ifmt-bad-arg.stderr @@ -178,7 +178,7 @@ error: invalid format string: expected `'}'`, found `'t'` LL | ninth number: { | - because of this opening brace LL | tenth number: {}", - | ^ expected `}` in format string + | ^ expected `'}'` in format string | = note: if you intended to print `{`, you can escape it using `{{` diff --git a/tests/ui/impl-trait/auto-trait-leak.stderr b/tests/ui/impl-trait/auto-trait-leak.stderr index 92a9763bc9b5..a024cff0b8da 100644 --- a/tests/ui/impl-trait/auto-trait-leak.stderr +++ b/tests/ui/impl-trait/auto-trait-leak.stderr @@ -33,6 +33,7 @@ LL | | fn send(_: T) {} LL | | Rc::new(String::from("foo")) LL | | } | |_^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error[E0391]: cycle detected when computing type of `cycle1::{opaque#0}` --> $DIR/auto-trait-leak.rs:11:16 @@ -68,6 +69,7 @@ LL | | fn send(_: T) {} LL | | Rc::new(String::from("foo")) LL | | } | |_^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: cannot check whether the hidden type of opaque type satisfies auto traits --> $DIR/auto-trait-leak.rs:21:10 diff --git a/tests/ui/impl-trait/defined-by-trait-resolution.rs b/tests/ui/impl-trait/defined-by-trait-resolution.rs new file mode 100644 index 000000000000..1744046ddbb7 --- /dev/null +++ b/tests/ui/impl-trait/defined-by-trait-resolution.rs @@ -0,0 +1,12 @@ +//! The trait query `foo: Fn() -> u8` is a valid defining use of RPIT. + +// build-pass + +fn returns_u8(_: impl Fn() -> u8) {} + +pub fn foo() -> impl Sized { + returns_u8(foo); + 0u8 +} + +fn main() {} diff --git a/tests/ui/infinite/infinite-trait-alias-recursion.stderr b/tests/ui/infinite/infinite-trait-alias-recursion.stderr index 683987b4943d..39d7aa4c16aa 100644 --- a/tests/ui/infinite/infinite-trait-alias-recursion.stderr +++ b/tests/ui/infinite/infinite-trait-alias-recursion.stderr @@ -21,6 +21,7 @@ note: cycle used when collecting item types in top-level module | LL | trait T1 = T2; | ^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/infinite/infinite-type-alias-mutual-recursion.stderr b/tests/ui/infinite/infinite-type-alias-mutual-recursion.stderr index 7f82b294434f..bbdb1f70b803 100644 --- a/tests/ui/infinite/infinite-type-alias-mutual-recursion.stderr +++ b/tests/ui/infinite/infinite-type-alias-mutual-recursion.stderr @@ -28,6 +28,7 @@ LL | | type X3 = X1; LL | | LL | | fn main() {} | |____________^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/infinite/infinite-vec-type-recursion.stderr b/tests/ui/infinite/infinite-vec-type-recursion.stderr index 1e487a5b11c2..a21b033a9a9a 100644 --- a/tests/ui/infinite/infinite-vec-type-recursion.stderr +++ b/tests/ui/infinite/infinite-vec-type-recursion.stderr @@ -16,6 +16,7 @@ LL | | LL | | LL | | fn main() { let b: X = Vec::new(); } | |____________________________________^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/inline-const/interpolated.rs b/tests/ui/inline-const/interpolated.rs new file mode 100644 index 000000000000..3fcc621c9469 --- /dev/null +++ b/tests/ui/inline-const/interpolated.rs @@ -0,0 +1,32 @@ +// check-pass + +#![feature(inline_const)] + +// This used to be unsupported since the parser first tries to check if we have +// any nested items, and then checks for statements (and expressions). The heuristic +// that we were using to detect the beginning of a const item was incorrect, so +// this used to fail. +macro_rules! m { + ($b:block) => { + fn foo() { + const $b + } + } +} + +// This has worked since inline-consts were implemented, since the position that +// the const block is located at doesn't support nested items (e.g. because +// `let x = const X: u32 = 1;` is invalid), so there's no ambiguity parsing the +// inline const. +macro_rules! m2 { + ($b:block) => { + fn foo2() { + let _ = const $b; + } + } +} + +m!({}); +m2!({}); + +fn main() {} diff --git a/tests/ui/issues/issue-17252.stderr b/tests/ui/issues/issue-17252.stderr index aca5242b2968..daaf82e80ade 100644 --- a/tests/ui/issues/issue-17252.stderr +++ b/tests/ui/issues/issue-17252.stderr @@ -10,6 +10,7 @@ note: cycle used when const-evaluating + checking `main::{constant#0}` | LL | let _x: [u8; FOO]; // caused stack overflow prior to fix | ^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/issues/issue-20772.stderr b/tests/ui/issues/issue-20772.stderr index 416fd8c062fa..0c7e728c67e8 100644 --- a/tests/ui/issues/issue-20772.stderr +++ b/tests/ui/issues/issue-20772.stderr @@ -10,6 +10,7 @@ note: cycle used when computing the super predicates of `T` | LL | trait T : Iterator | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/issues/issue-21177.stderr b/tests/ui/issues/issue-21177.stderr index 6877a1846050..8b749edcc77f 100644 --- a/tests/ui/issues/issue-21177.stderr +++ b/tests/ui/issues/issue-21177.stderr @@ -10,6 +10,7 @@ note: cycle used when computing explicit predicates of `foo` | LL | fn foo>() { } | ^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/issues/issue-23302-1.stderr b/tests/ui/issues/issue-23302-1.stderr index 9366050d7ecd..d807e24403e0 100644 --- a/tests/ui/issues/issue-23302-1.stderr +++ b/tests/ui/issues/issue-23302-1.stderr @@ -10,6 +10,7 @@ note: cycle used when simplifying constant for the type system `X::A::{constant# | LL | A = X::A as isize, | ^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/issues/issue-23302-2.stderr b/tests/ui/issues/issue-23302-2.stderr index b97ae287a47a..91b39dba1ba2 100644 --- a/tests/ui/issues/issue-23302-2.stderr +++ b/tests/ui/issues/issue-23302-2.stderr @@ -10,6 +10,7 @@ note: cycle used when simplifying constant for the type system `Y::A::{constant# | LL | A = Y::B as isize, | ^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/issues/issue-23302-3.stderr b/tests/ui/issues/issue-23302-3.stderr index c6cafe575e51..6b708d81f73f 100644 --- a/tests/ui/issues/issue-23302-3.stderr +++ b/tests/ui/issues/issue-23302-3.stderr @@ -15,6 +15,7 @@ note: cycle used when simplifying constant for the type system `A` | LL | const A: i32 = B; | ^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/issues/issue-34373.stderr b/tests/ui/issues/issue-34373.stderr index 8be3cfa72fb2..0f0821518a42 100644 --- a/tests/ui/issues/issue-34373.stderr +++ b/tests/ui/issues/issue-34373.stderr @@ -21,6 +21,7 @@ LL | | fn foo(_: T) {} LL | | fn main() { LL | | } | |_^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/lint/lint-qualification.fixed b/tests/ui/lint/lint-qualification.fixed new file mode 100644 index 000000000000..c14493013623 --- /dev/null +++ b/tests/ui/lint/lint-qualification.fixed @@ -0,0 +1,21 @@ +// run-rustfix +#![deny(unused_qualifications)] +#![allow(deprecated)] + +mod foo { + pub fn bar() {} +} + +fn main() { + use foo::bar; + bar(); //~ ERROR: unnecessary qualification + bar(); + + let _ = || -> Result<(), ()> { try!(Ok(())); Ok(()) }; // issue #37345 + + macro_rules! m { () => { + $crate::foo::bar(); // issue #37357 + ::foo::bar(); // issue #38682 + } } + m!(); +} diff --git a/tests/ui/lint/lint-qualification.rs b/tests/ui/lint/lint-qualification.rs index 0cace0ca0355..80904303559d 100644 --- a/tests/ui/lint/lint-qualification.rs +++ b/tests/ui/lint/lint-qualification.rs @@ -1,3 +1,4 @@ +// run-rustfix #![deny(unused_qualifications)] #![allow(deprecated)] diff --git a/tests/ui/lint/lint-qualification.stderr b/tests/ui/lint/lint-qualification.stderr index d09cb78c4f01..90a06bc6cbe5 100644 --- a/tests/ui/lint/lint-qualification.stderr +++ b/tests/ui/lint/lint-qualification.stderr @@ -1,18 +1,19 @@ error: unnecessary qualification - --> $DIR/lint-qualification.rs:10:5 + --> $DIR/lint-qualification.rs:11:5 | LL | foo::bar(); | ^^^^^^^^ | note: the lint level is defined here - --> $DIR/lint-qualification.rs:1:9 + --> $DIR/lint-qualification.rs:2:9 | LL | #![deny(unused_qualifications)] | ^^^^^^^^^^^^^^^^^^^^^ -help: replace it with the unqualified path +help: remove the unnecessary path segments + | +LL - foo::bar(); +LL + bar(); | -LL | bar(); - | ~~~ error: aborting due to previous error diff --git a/tests/ui/modules/issue-107649.stderr b/tests/ui/modules/issue-107649.stderr index 38a910b57b47..5705e84e0d99 100644 --- a/tests/ui/modules/issue-107649.stderr +++ b/tests/ui/modules/issue-107649.stderr @@ -11,7 +11,7 @@ help: consider annotating `Dummy` with `#[derive(Debug)]` --> $DIR/auxiliary/dummy_lib.rs:2:1 | 2 + #[derive(Debug)] -3 | #[path = "auxiliary/dummy_lib.rs"] +3 | pub struct Dummy; | error: aborting due to previous error diff --git a/tests/ui/recursion/issue-26548-recursion-via-normalize.rs b/tests/ui/recursion/issue-26548-recursion-via-normalize.rs index 91958dffcf4d..6c7fc4beb543 100644 --- a/tests/ui/recursion/issue-26548-recursion-via-normalize.rs +++ b/tests/ui/recursion/issue-26548-recursion-via-normalize.rs @@ -1,4 +1,5 @@ //~ ERROR cycle detected when computing layout of `core::option::Option` +//~| NOTE see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information //~| NOTE ...which requires computing layout of `S`... //~| NOTE ...which requires computing layout of `core::option::Option<::It>`... //~| NOTE ...which again requires computing layout of `core::option::Option`, completing the cycle diff --git a/tests/ui/recursion/issue-26548-recursion-via-normalize.stderr b/tests/ui/recursion/issue-26548-recursion-via-normalize.stderr index a75097cdbfbd..514bed607003 100644 --- a/tests/ui/recursion/issue-26548-recursion-via-normalize.stderr +++ b/tests/ui/recursion/issue-26548-recursion-via-normalize.stderr @@ -4,6 +4,7 @@ error[E0391]: cycle detected when computing layout of `core::option::Option` = note: ...which requires computing layout of `core::option::Option<::It>`... = note: ...which again requires computing layout of `core::option::Option`, completing the cycle = note: cycle used when computing layout of `core::option::Option<::It>` + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/recursion/recursive-static-definition.stderr b/tests/ui/recursion/recursive-static-definition.stderr index 1359761457a6..b112228d4039 100644 --- a/tests/ui/recursion/recursive-static-definition.stderr +++ b/tests/ui/recursion/recursive-static-definition.stderr @@ -18,6 +18,7 @@ LL | | LL | | LL | | fn main() {} | |____________^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.fixed b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.fixed new file mode 100644 index 000000000000..e730f94660bb --- /dev/null +++ b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.fixed @@ -0,0 +1,31 @@ +// run-rustfix + +#![deny(unused_qualifications)] +#![feature(unsized_fn_params)] + +#[allow(unused_imports)] +use std::ops; +use std::ops::Index; + +pub struct A; + +impl Index for A { + //~^ ERROR unnecessary qualification + type Output = (); + fn index(&self, _: str) -> &Self::Output { + &() + } +} + +mod inner { + pub trait Trait {} +} + +// the import needs to be here for the lint to show up +#[allow(unused_imports)] +use inner::Trait; + +impl Trait for () {} +//~^ ERROR unnecessary qualification + +fn main() {} diff --git a/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.rs b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.rs new file mode 100644 index 000000000000..641c892e3de9 --- /dev/null +++ b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.rs @@ -0,0 +1,31 @@ +// run-rustfix + +#![deny(unused_qualifications)] +#![feature(unsized_fn_params)] + +#[allow(unused_imports)] +use std::ops; +use std::ops::Index; + +pub struct A; + +impl ops::Index for A { + //~^ ERROR unnecessary qualification + type Output = (); + fn index(&self, _: str) -> &Self::Output { + &() + } +} + +mod inner { + pub trait Trait {} +} + +// the import needs to be here for the lint to show up +#[allow(unused_imports)] +use inner::Trait; + +impl inner::Trait for () {} +//~^ ERROR unnecessary qualification + +fn main() {} diff --git a/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.stderr b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.stderr new file mode 100644 index 000000000000..d9c7fd21871b --- /dev/null +++ b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.stderr @@ -0,0 +1,31 @@ +error: unnecessary qualification + --> $DIR/issue-113808-invalid-unused-qualifications-suggestion.rs:12:6 + | +LL | impl ops::Index for A { + | ^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/issue-113808-invalid-unused-qualifications-suggestion.rs:3:9 + | +LL | #![deny(unused_qualifications)] + | ^^^^^^^^^^^^^^^^^^^^^ +help: remove the unnecessary path segments + | +LL - impl ops::Index for A { +LL + impl Index for A { + | + +error: unnecessary qualification + --> $DIR/issue-113808-invalid-unused-qualifications-suggestion.rs:28:6 + | +LL | impl inner::Trait for () {} + | ^^^^^^^^^^^^^^^^ + | +help: remove the unnecessary path segments + | +LL - impl inner::Trait for () {} +LL + impl Trait for () {} + | + +error: aborting due to 2 previous errors + diff --git a/tests/ui/resolve/resolve-self-in-impl.stderr b/tests/ui/resolve/resolve-self-in-impl.stderr index 9f9ed68898f6..183a17171f7f 100644 --- a/tests/ui/resolve/resolve-self-in-impl.stderr +++ b/tests/ui/resolve/resolve-self-in-impl.stderr @@ -56,6 +56,7 @@ LL | | trait Tr { LL | | LL | | fn main() {} | |____________^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 6 previous errors diff --git a/tests/ui/resolve/unused-qualifications-suggestion.stderr b/tests/ui/resolve/unused-qualifications-suggestion.stderr index c8e91e07295b..e3dac37fc6e2 100644 --- a/tests/ui/resolve/unused-qualifications-suggestion.stderr +++ b/tests/ui/resolve/unused-qualifications-suggestion.stderr @@ -9,10 +9,11 @@ note: the lint level is defined here | LL | #![deny(unused_qualifications)] | ^^^^^^^^^^^^^^^^^^^^^ -help: replace it with the unqualified path +help: remove the unnecessary path segments + | +LL - foo::bar(); +LL + bar(); | -LL | bar(); - | ~~~ error: unnecessary qualification --> $DIR/unused-qualifications-suggestion.rs:21:5 @@ -20,10 +21,11 @@ error: unnecessary qualification LL | baz::qux::quux(); | ^^^^^^^^^^^^^^ | -help: replace it with the unqualified path +help: remove the unnecessary path segments + | +LL - baz::qux::quux(); +LL + quux(); | -LL | quux(); - | ~~~~ error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs index d7a418959bf5..880907b24b46 100644 --- a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs +++ b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs @@ -6,6 +6,10 @@ // compile-flags: --crate-type lib --emit link // normalize-stderr-test: "[^ ']*/dlltool.exe" -> "$$DLLTOOL" // normalize-stderr-test: "[^ ]*/foo.def" -> "$$DEF_FILE" +// normalize-stderr-test: "[^ ]*/foo.lib" -> "$$LIB_FILE" +// normalize-stderr-test: "-m [^ ]*" -> "$$TARGET_MACHINE" +// normalize-stderr-test: "-f [^ ]*" -> "$$ASM_FLAGS" +// normalize-stderr-test: "--temp-prefix [^ ]*/foo.dll" -> "$$TEMP_PREFIX" #[link(name = "foo", kind = "raw-dylib")] extern "C" { // `@1` is an invalid name to export, as it usually indicates that something diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.stderr b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.stderr index 020ac6a2b670..cc532ccc4510 100644 --- a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.stderr +++ b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.stderr @@ -1,4 +1,5 @@ -error: Dlltool could not create import library: +error: Dlltool could not create import library with $DLLTOOL -d $DEF_FILE -D foo.dll -l $LIB_FILE $TARGET_MACHINE $ASM_FLAGS --no-leading-underscore $TEMP_PREFIX: + $DLLTOOL: Syntax error in def file $DEF_FILE:1 error: aborting due to previous error diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr b/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr index 510108405488..dfd24566953f 100644 --- a/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr +++ b/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr @@ -2,7 +2,7 @@ error: multiple declarations of external function `f` from library `foo.dll` hav --> $DIR/multiple-declarations.rs:13:9 | LL | fn f(x: i32); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr b/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr index f8265ae69194..f69275a01253 100644 --- a/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr +++ b/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr @@ -2,7 +2,7 @@ error: ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture --> $DIR/unsupported-abi.rs:6:5 | LL | fn f(x: i32); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/simd/intrinsic/float-minmax-pass.rs b/tests/ui/simd/intrinsic/float-minmax-pass.rs index d79be61f9099..968b074b6ef1 100644 --- a/tests/ui/simd/intrinsic/float-minmax-pass.rs +++ b/tests/ui/simd/intrinsic/float-minmax-pass.rs @@ -21,7 +21,7 @@ fn main() { #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] let nan = f32::NAN; - // MIPS hardware treats f32::NAN as SNAN. Clear the signaling bit. + // MIPS hardware except MIPS R6 treats f32::NAN as SNAN. Clear the signaling bit. // See https://github.com/rust-lang/rust/issues/52746. #[cfg(any(target_arch = "mips", target_arch = "mips64"))] let nan = f32::from_bits(f32::NAN.to_bits() - 1); diff --git a/tests/ui/sized/recursive-type-2.stderr b/tests/ui/sized/recursive-type-2.stderr index d0e6e9db07e9..0f72f74145e8 100644 --- a/tests/ui/sized/recursive-type-2.stderr +++ b/tests/ui/sized/recursive-type-2.stderr @@ -7,6 +7,7 @@ note: cycle used when elaborating drops for `main` | LL | fn main() { | ^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/traits/new-solver/alias-bound-preference.rs b/tests/ui/traits/new-solver/alias-bound-preference.rs new file mode 100644 index 000000000000..e4e0f634ef76 --- /dev/null +++ b/tests/ui/traits/new-solver/alias-bound-preference.rs @@ -0,0 +1,39 @@ +// revisions: old next +//[next] compile-flags: -Ztrait-solver=next +// run-pass + +// A test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/45. + +trait Trait { + type Assoc: Into; +} +impl> Trait for T { + type Assoc = T; +} +fn prefer_alias_bound_projection(x: T::Assoc) { + // There are two possible types for `x`: + // - `u32` by using the "alias bound" of `::Assoc` + // - `::Assoc`, i.e. `u16`, by using `impl From for T` + // + // We infer the type of `x` to be `u32` here as it is highly likely + // that this is expected by the user. + let x = x.into(); + assert_eq!(std::mem::size_of_val(&x), 4); +} + +fn impl_trait() -> impl Into { + 0u16 +} + +fn main() { + // There are two possible types for `x`: + // - `u32` by using the "alias bound" of `impl Into` + // - `impl Into`, i.e. `u16`, by using `impl From for T` + // + // We infer the type of `x` to be `u32` here as it is highly likely + // that this is expected by the user. + let x = impl_trait().into(); + assert_eq!(std::mem::size_of_val(&x), 4); + + prefer_alias_bound_projection::(1); +} diff --git a/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr b/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr index ca98e1831507..62c732fb1d95 100644 --- a/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr +++ b/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr @@ -10,6 +10,7 @@ note: cycle used when collecting item types in top-level module | LL | trait A: B + A {} | ^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/transmutability/issue-110892.rs b/tests/ui/transmutability/issue-110892.rs new file mode 100644 index 000000000000..ce926b399963 --- /dev/null +++ b/tests/ui/transmutability/issue-110892.rs @@ -0,0 +1,40 @@ +// check-fail +#![feature(generic_const_exprs, transmutability)] +#![allow(incomplete_features)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable< + Src, + Dst, + Context, + const ASSUME_ALIGNMENT: bool, + const ASSUME_LIFETIMES: bool, + const ASSUME_SAFETY: bool, + const ASSUME_VALIDITY: bool, + >() + where + Dst: BikeshedIntrinsicFrom< + Src, + Context, + { from_options(ASSUME_ALIGNMENT, ASSUME_LIFETIMES, ASSUME_SAFETY, ASSUME_VALIDITY) } + >, + {} + + // This should not cause an ICE + const fn from_options( + , //~ ERROR expected parameter name, found `,` + , //~ ERROR expected parameter name, found `,` + , //~ ERROR expected parameter name, found `,` + , //~ ERROR expected parameter name, found `,` + ) -> Assume {} //~ ERROR mismatched types +} + +fn main() { + struct Context; + #[repr(C)] struct Src; + #[repr(C)] struct Dst; + + assert::is_transmutable::(); +} diff --git a/tests/ui/transmutability/issue-110892.stderr b/tests/ui/transmutability/issue-110892.stderr new file mode 100644 index 000000000000..13654307aee7 --- /dev/null +++ b/tests/ui/transmutability/issue-110892.stderr @@ -0,0 +1,36 @@ +error: expected parameter name, found `,` + --> $DIR/issue-110892.rs:27:9 + | +LL | , + | ^ expected parameter name + +error: expected parameter name, found `,` + --> $DIR/issue-110892.rs:28:9 + | +LL | , + | ^ expected parameter name + +error: expected parameter name, found `,` + --> $DIR/issue-110892.rs:29:9 + | +LL | , + | ^ expected parameter name + +error: expected parameter name, found `,` + --> $DIR/issue-110892.rs:30:9 + | +LL | , + | ^ expected parameter name + +error[E0308]: mismatched types + --> $DIR/issue-110892.rs:31:10 + | +LL | const fn from_options( + | ------------ implicitly returns `()` as its body has no tail or `return` expression +... +LL | ) -> Assume {} + | ^^^^^^ expected `Assume`, found `()` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr index c943a4918ba6..aa79b1a57c4c 100644 --- a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr +++ b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr @@ -67,6 +67,7 @@ LL | | V2 = Self::V1 as u8 + 1, // OK; See #50072. LL | | LL | | fn main() {} | |____________^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr b/tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr index dd56c59bf5f2..5bd0f76c31fb 100644 --- a/tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr +++ b/tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr @@ -16,6 +16,7 @@ note: cycle used when checking item types in module `m` | LL | mod m { | ^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}` --> $DIR/auto-trait-leakage3.rs:7:20 @@ -34,6 +35,7 @@ note: cycle used when checking item types in module `m` | LL | mod m { | ^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: cannot check whether the hidden type of `auto_trait_leakage3[211d]::m::Foo::{opaque#0}` satisfies auto traits --> $DIR/auto-trait-leakage3.rs:16:17 diff --git a/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs b/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs new file mode 100644 index 000000000000..5a421ea1dc02 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs @@ -0,0 +1,19 @@ +// User type annotation in fn bodies is a a valid defining site for opaque types. +// check-pass +#![feature(type_alias_impl_trait)] + +trait Equate { type Proj; } +impl Equate for T { type Proj = T; } + +trait Indirect { type Ty; } +impl> Indirect for (A, B) { type Ty = (); } + +type Opq = impl Sized; +fn define_1(_: Opq) { + let _ = None::<<(Opq, u8) as Indirect>::Ty>; +} +fn define_2() -> Opq { + 0u8 +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/inference-cycle.stderr b/tests/ui/type-alias-impl-trait/inference-cycle.stderr index 4d5f367476b7..41530dda983a 100644 --- a/tests/ui/type-alias-impl-trait/inference-cycle.stderr +++ b/tests/ui/type-alias-impl-trait/inference-cycle.stderr @@ -16,6 +16,7 @@ note: cycle used when checking item types in module `m` | LL | mod m { | ^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}` --> $DIR/inference-cycle.rs:5:20 @@ -34,6 +35,7 @@ note: cycle used when checking item types in module `m` | LL | mod m { | ^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: cannot check whether the hidden type of `inference_cycle[4ecc]::m::Foo::{opaque#0}` satisfies auto traits --> $DIR/inference-cycle.rs:16:17 diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr index 2565a28b4935..6148131b491f 100644 --- a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr +++ b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr @@ -23,6 +23,7 @@ LL | | type Bug = impl Fn(T) -> U + Copy; LL | | CONST_BUG(0); LL | | } | |_^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error[E0277]: the trait bound `U: From` is not satisfied --> $DIR/issue-53092-2.rs:9:5 diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs new file mode 100644 index 000000000000..10588398c9d7 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs @@ -0,0 +1,21 @@ +// issue: 113314 + +#![feature(type_alias_impl_trait)] + +type Op = impl std::fmt::Display; +fn foo() -> Op { &"hello world" } + +fn transform() -> impl std::fmt::Display { + &0usize +} +fn bad() -> Op { + transform::() + //~^ ERROR concrete type differs from previous defining opaque type use +} + +fn main() { + let mut x = foo(); + println!("{x}"); + x = bad(); + println!("{x}"); +} diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr new file mode 100644 index 000000000000..7481557fcbad --- /dev/null +++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr @@ -0,0 +1,14 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/recursive-tait-conflicting-defn-2.rs:12:5 + | +LL | transform::() + | ^^^^^^^^^^^^^^^^^ expected `&'static &'static str`, got `impl std::fmt::Display` + | +note: previous use here + --> $DIR/recursive-tait-conflicting-defn-2.rs:6:18 + | +LL | fn foo() -> Op { &"hello world" } + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs new file mode 100644 index 000000000000..e221f4f3f55c --- /dev/null +++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs @@ -0,0 +1,34 @@ +// issue: 113596 + +#![feature(type_alias_impl_trait)] + +trait Test {} + +struct A; + +impl Test for A {} + +struct B { + inner: T, +} + +impl Test for B {} + +type TestImpl = impl Test; + +fn test() -> TestImpl { + A +} + +fn make_option() -> Option { + Some(test()) +} + +fn make_option2() -> Option { + let inner = make_option().unwrap(); + + Some(B { inner }) + //~^ ERROR concrete type differs from previous defining opaque type use +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr new file mode 100644 index 000000000000..e4209643b7a3 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr @@ -0,0 +1,14 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/recursive-tait-conflicting-defn.rs:30:3 + | +LL | Some(B { inner }) + | ^^^^^^^^^^^^^^^^^ expected `A`, got `B` + | +note: previous use here + --> $DIR/recursive-tait-conflicting-defn.rs:20:3 + | +LL | A + | ^ + +error: aborting due to previous error + diff --git a/tests/ui/type-alias-impl-trait/reveal_local.stderr b/tests/ui/type-alias-impl-trait/reveal_local.stderr index 0c5ef4a6fb41..813185c13779 100644 --- a/tests/ui/type-alias-impl-trait/reveal_local.stderr +++ b/tests/ui/type-alias-impl-trait/reveal_local.stderr @@ -22,6 +22,7 @@ LL | | LL | | LL | | fn main() {} | |____________^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error[E0391]: cycle detected when computing type of `Foo::{opaque#0}` --> $DIR/reveal_local.rs:5:12 @@ -46,6 +47,7 @@ LL | | LL | | LL | | fn main() {} | |____________^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits --> $DIR/reveal_local.rs:15:15 @@ -92,6 +94,7 @@ LL | | LL | | LL | | fn main() {} | |____________^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits --> $DIR/reveal_local.rs:25:15 diff --git a/triagebot.toml b/triagebot.toml index 1a435ff074ee..cc26c3b3e7b9 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -457,7 +457,7 @@ cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"] [mentions."compiler/rustc_smir"] message = "This PR changes Stable MIR" -cc = ["@oli-obk", "@celinval"] +cc = ["@oli-obk", "@celinval", "@spastorino"] [mentions."compiler/rustc_target/src/spec"] message = """