diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 631ed54cc024b..2aac669d744a9 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -128,6 +128,17 @@ impl<'a> Diagnostic<'a, ()> } } +/// Type used to emit diagnostic through a closure instead of implementing the `Diagnostic` trait. +pub struct DiagDecorator)>(pub F); + +impl<'a, F: FnOnce(&mut Diag<'_, ()>)> Diagnostic<'a, ()> for DiagDecorator { + fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { + let mut diag = Diag::new(dcx, level, ""); + (self.0)(&mut diag); + diag + } +} + /// Trait implemented by error types. This should not be implemented manually. Instead, use /// `#[derive(Subdiagnostic)]` -- see [rustc_macros::Subdiagnostic]. #[rustc_diagnostic_item = "Subdiagnostic"] diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 0a111538fc89a..a96eceb6c715d 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -36,8 +36,8 @@ pub use anstyle::{ pub use codes::*; pub use decorate_diag::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer}; pub use diagnostic::{ - BugAbort, Diag, DiagInner, DiagLocation, DiagStyledString, Diagnostic, EmissionGuarantee, - FatalAbort, StringPart, Subdiag, Subdiagnostic, + BugAbort, Diag, DiagDecorator, DiagInner, DiagLocation, DiagStyledString, Diagnostic, + EmissionGuarantee, FatalAbort, StringPart, Subdiag, Subdiagnostic, }; pub use diagnostic_impls::{ DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter, diff --git a/compiler/rustc_lint/src/default_could_be_derived.rs b/compiler/rustc_lint/src/default_could_be_derived.rs index 0db2f6a3565c7..9d4b79a45453a 100644 --- a/compiler/rustc_lint/src/default_could_be_derived.rs +++ b/compiler/rustc_lint/src/default_could_be_derived.rs @@ -1,5 +1,5 @@ use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{Applicability, Diag}; +use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, Level}; use rustc_hir as hir; use rustc_middle::ty; use rustc_middle::ty::TyCtxt; @@ -147,50 +147,59 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived { let hir_id = cx.tcx.local_def_id_to_hir_id(impl_id); let span = cx.tcx.hir_span_with_body(hir_id); - cx.tcx.node_span_lint(DEFAULT_OVERRIDES_DEFAULT_FIELDS, hir_id, span, |diag| { - mk_lint(cx.tcx, diag, type_def_id, orig_fields, fields, span); - }); + cx.tcx.emit_node_span_lint( + DEFAULT_OVERRIDES_DEFAULT_FIELDS, + hir_id, + span, + WrongDefaultImpl { tcx: cx.tcx, type_def_id, orig_fields, fields, impl_span: span }, + ); } } -fn mk_lint( - tcx: TyCtxt<'_>, - diag: &mut Diag<'_, ()>, +struct WrongDefaultImpl<'a, 'hir, 'tcx> { + tcx: TyCtxt<'tcx>, type_def_id: DefId, - orig_fields: FxHashMap>, - fields: &[hir::ExprField<'_>], + orig_fields: FxHashMap>, + fields: &'a [hir::ExprField<'hir>], impl_span: Span, -) { - diag.primary_message("`Default` impl doesn't use the declared default field values"); - - // For each field in the struct expression - // - if the field in the type has a default value, it should be removed - // - elif the field is an expression that could be a default value, it should be used as the - // field's default value (FIXME: not done). - // - else, we wouldn't touch this field, it would remain in the manual impl - let mut removed_all_fields = true; - for field in fields { - if orig_fields.get(&field.ident.name).and_then(|f| f.default).is_some() { - diag.span_label(field.expr.span, "this field has a default value"); - } else { - removed_all_fields = false; +} + +impl<'a, 'b, 'hir, 'tcx> Diagnostic<'a, ()> for WrongDefaultImpl<'b, 'hir, 'tcx> { + fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { + let Self { tcx, type_def_id, orig_fields, fields, impl_span } = self; + let mut diag = + Diag::new(dcx, level, "`Default` impl doesn't use the declared default field values"); + + // For each field in the struct expression + // - if the field in the type has a default value, it should be removed + // - elif the field is an expression that could be a default value, it should be used as the + // field's default value (FIXME: not done). + // - else, we wouldn't touch this field, it would remain in the manual impl + let mut removed_all_fields = true; + for field in fields { + if orig_fields.get(&field.ident.name).and_then(|f| f.default).is_some() { + diag.span_label(field.expr.span, "this field has a default value"); + } else { + removed_all_fields = false; + } } - } - if removed_all_fields { - let msg = "to avoid divergence in behavior between `Struct { .. }` and \ - `::default()`, derive the `Default`"; - diag.multipart_suggestion( - msg, - vec![ - (tcx.def_span(type_def_id).shrink_to_lo(), "#[derive(Default)] ".to_string()), - (impl_span, String::new()), - ], - Applicability::MachineApplicable, - ); - } else { - let msg = "use the default values in the `impl` with `Struct { mandatory_field, .. }` to \ - avoid them diverging over time"; - diag.help(msg); + if removed_all_fields { + diag.multipart_suggestion( + "to avoid divergence in behavior between `Struct { .. }` and \ + `::default()`, derive the `Default`", + vec![ + (tcx.def_span(type_def_id).shrink_to_lo(), "#[derive(Default)] ".to_string()), + (impl_span, String::new()), + ], + Applicability::MachineApplicable, + ); + } else { + diag.help( + "use the default values in the `impl` with `Struct { mandatory_field, .. }` to \ + avoid them diverging over time", + ); + } + diag } } diff --git a/compiler/rustc_lint/src/transmute.rs b/compiler/rustc_lint/src/transmute.rs index cbb9ca6aa00f1..4ee25ac008eb7 100644 --- a/compiler/rustc_lint/src/transmute.rs +++ b/compiler/rustc_lint/src/transmute.rs @@ -357,15 +357,24 @@ fn check_unnecessary_transmute<'tcx>( _ => return, }; - cx.tcx.node_span_lint(UNNECESSARY_TRANSMUTES, expr.hir_id, expr.span, |diag| { - diag.primary_message("unnecessary transmute"); - if let Some(sugg) = sugg { - diag.multipart_suggestion("replace this with", sugg, Applicability::MachineApplicable); - } - if let Some(help) = help { - diag.help(help); - } - }); + cx.tcx.emit_node_span_lint( + UNNECESSARY_TRANSMUTES, + expr.hir_id, + expr.span, + rustc_errors::DiagDecorator(|diag| { + diag.primary_message("unnecessary transmute"); + if let Some(sugg) = sugg { + diag.multipart_suggestion( + "replace this with", + sugg, + Applicability::MachineApplicable, + ); + } + if let Some(help) = help { + diag.help(help); + } + }), + ); } #[derive(Diagnostic)] diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 628d358146846..06e4a287460b2 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -564,9 +564,14 @@ impl<'tcx> TyCtxt<'tcx> { unmarked: impl FnOnce(Span, DefId), ) -> bool { let soft_handler = |lint, span, msg: String| { - self.node_span_lint(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| { - lint.primary_message(msg); - }) + self.emit_node_span_lint( + lint, + id.unwrap_or(hir::CRATE_HIR_ID), + span, + rustc_errors::DiagDecorator(|lint| { + lint.primary_message(msg); + }), + ); }; let eval_result = self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable); diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 89034981cbd64..00ac8e66cda75 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -139,15 +139,15 @@ impl<'tcx> TyCtxt<'tcx> { let mir_body = self.mir_for_ctfe(cid.instance.def_id()); if mir_body.is_polymorphic { let Some(local_def_id) = ct.def.as_local() else { return }; - self.node_span_lint( + self.emit_node_span_lint( lint::builtin::CONST_EVALUATABLE_UNCHECKED, self.local_def_id_to_hir_id(local_def_id), self.def_span(ct.def), - |lint| { + rustc_errors::DiagDecorator(|lint| { lint.primary_message( "cannot use constants which depend on generic parameters in types", ); - }, + }), ) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 64af9e7f0998b..80f748f640871 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -38,6 +38,7 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::limit::Limit; use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, Node, TraitCandidate, find_attr}; use rustc_index::IndexVec; +use rustc_macros::Diagnostic; use rustc_session::Session; use rustc_session::config::CrateType; use rustc_session::cstore::{CrateStoreDyn, Untracked}; @@ -1685,6 +1686,12 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn report_unused_features(self) { + #[derive(Diagnostic)] + #[diag("feature `{$feature}` is declared but not used")] + struct UnusedFeature { + feature: Symbol, + } + // Collect first to avoid holding the lock while linting. let used_features = self.sess.used_features.lock(); let unused_features = self @@ -1703,13 +1710,11 @@ impl<'tcx> TyCtxt<'tcx> { .collect::>(); for (feature, span) in unused_features { - self.node_span_lint( + self.emit_node_span_lint( rustc_session::lint::builtin::UNUSED_FEATURES, CRATE_HIR_ID, span, - |lint| { - lint.primary_message(format!("feature `{}` is declared but not used", feature)); - }, + UnusedFeature { feature }, ); } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/migration.rs b/compiler/rustc_mir_build/src/thir/pattern/migration.rs index 9a5cc08e6c4c5..96021704d3292 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/migration.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/migration.rs @@ -55,10 +55,15 @@ impl<'a> PatMigration<'a> { self.format_subdiagnostics(&mut err); err.emit(); } else { - tcx.node_span_lint(lint::builtin::RUST_2024_INCOMPATIBLE_PAT, pat_id, spans, |diag| { - diag.primary_message(primary_message); - self.format_subdiagnostics(diag); - }); + tcx.emit_node_span_lint( + lint::builtin::RUST_2024_INCOMPATIBLE_PAT, + pat_id, + spans, + rustc_errors::DiagDecorator(|diag| { + diag.primary_message(primary_message); + self.format_subdiagnostics(diag); + }), + ); } } diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index 6f0f9cc23a55d..00b67b6564594 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -19,11 +19,11 @@ pub(crate) fn emit_inline_always_target_feature_diagnostic<'a, 'tcx>( caller_def_id: DefId, callee_only: &[&'a str], ) { - tcx.node_span_lint( + tcx.emit_node_span_lint( lint::builtin::INLINE_ALWAYS_MISMATCHING_TARGET_FEATURES, tcx.local_def_id_to_hir_id(caller_def_id.as_local().unwrap()), call_span, - |lint| { + rustc_errors::DiagDecorator(|lint| { let callee = tcx.def_path_str(callee_def_id); let caller = tcx.def_path_str(caller_def_id); @@ -46,7 +46,7 @@ pub(crate) fn emit_inline_always_target_feature_diagnostic<'a, 'tcx>( format!("#[target_feature(enable = \"{feats}\")]\n"), lint::Applicability::MaybeIncorrect, ); - }, + }), ); } diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 038168ca638b4..32b1e93bf98be 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -9,6 +9,7 @@ use derive_where::derive_where; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::SolverTraitLangItem; use rustc_type_ir::search_graph::CandidateHeadUsages; +use rustc_type_ir::solve::Certainty::Maybe; use rustc_type_ir::solve::{AliasBoundKind, SizedTraitKind}; use rustc_type_ir::{ self as ty, Interner, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, @@ -138,8 +139,10 @@ where .enter_single_candidate(|ecx| { Self::match_assumption(ecx, goal, assumption, |ecx| { ecx.try_evaluate_added_goals()?; - source.set(ecx.characterize_param_env_assumption(goal.param_env, assumption)?); - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + let (src, certainty) = + ecx.characterize_param_env_assumption(goal.param_env, assumption)?; + source.set(src); + ecx.evaluate_added_goals_and_make_canonical_response(certainty) }) }); @@ -1228,21 +1231,26 @@ where &mut self, param_env: I::ParamEnv, assumption: I::Clause, - ) -> Result, NoSolution> { + ) -> Result<(CandidateSource, Certainty), NoSolution> { // FIXME: This should be fixed, but it also requires changing the behavior // in the old solver which is currently relied on. if assumption.has_bound_vars() { - return Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)); + return Ok((CandidateSource::ParamEnv(ParamEnvSource::NonGlobal), Certainty::Yes)); } match assumption.visit_with(&mut FindParamInClause { ecx: self, param_env, universes: vec![], + recursion_depth: 0, }) { ControlFlow::Break(Err(NoSolution)) => Err(NoSolution), - ControlFlow::Break(Ok(())) => Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)), - ControlFlow::Continue(()) => Ok(CandidateSource::ParamEnv(ParamEnvSource::Global)), + ControlFlow::Break(Ok(certainty)) => { + Ok((CandidateSource::ParamEnv(ParamEnvSource::NonGlobal), certainty)) + } + ControlFlow::Continue(()) => { + Ok((CandidateSource::ParamEnv(ParamEnvSource::Global), Certainty::Yes)) + } } } } @@ -1251,6 +1259,7 @@ struct FindParamInClause<'a, 'b, D: SolverDelegate, I: Interner> { ecx: &'a mut EvalCtxt<'b, D>, param_env: I::ParamEnv, universes: Vec>, + recursion_depth: usize, } impl TypeVisitor for FindParamInClause<'_, '_, D, I> @@ -1258,7 +1267,11 @@ where D: SolverDelegate, I: Interner, { - type Result = ControlFlow>; + // - `Continue(())`: no generic parameter was found, the type is global + // - `Break(Ok(Certainty::Yes))`: a generic parameter was found, the type is non-global + // - `Break(Ok(Certainty::Maybe(_)))`: the recursion limit reached, assume that the type is non-global + // - `Break(Err(NoSolution))`: normalization failed + type Result = ControlFlow>; fn visit_binder>(&mut self, t: &ty::Binder) -> Self::Result { self.universes.push(None); @@ -1275,12 +1288,24 @@ where if let ty::Placeholder(p) = ty.kind() { if p.universe() == ty::UniverseIndex::ROOT { - ControlFlow::Break(Ok(())) + ControlFlow::Break(Ok(Certainty::Yes)) } else { ControlFlow::Continue(()) } } else if ty.has_type_flags(TypeFlags::HAS_PLACEHOLDER | TypeFlags::HAS_RE_INFER) { - ty.super_visit_with(self) + self.recursion_depth += 1; + if self.recursion_depth > self.ecx.cx().recursion_limit() { + return ControlFlow::Break(Ok(Maybe { + cause: MaybeCause::Overflow { + suggest_increasing_limit: true, + keep_constraints: false, + }, + opaque_types_jank: OpaqueTypesJank::AllGood, + })); + } + let result = ty.super_visit_with(self); + self.recursion_depth -= 1; + result } else { ControlFlow::Continue(()) } @@ -1294,7 +1319,7 @@ where if let ty::ConstKind::Placeholder(p) = ct.kind() { if p.universe() == ty::UniverseIndex::ROOT { - ControlFlow::Break(Ok(())) + ControlFlow::Break(Ok(Certainty::Yes)) } else { ControlFlow::Continue(()) } @@ -1310,12 +1335,12 @@ where ty::ReStatic | ty::ReError(_) | ty::ReBound(..) => ControlFlow::Continue(()), ty::RePlaceholder(p) => { if p.universe() == ty::UniverseIndex::ROOT { - ControlFlow::Break(Ok(())) + ControlFlow::Break(Ok(Certainty::Yes)) } else { ControlFlow::Continue(()) } } - ty::ReVar(_) => ControlFlow::Break(Ok(())), + ty::ReVar(_) => ControlFlow::Break(Ok(Certainty::Yes)), ty::ReErased | ty::ReEarlyParam(_) | ty::ReLateParam(_) => { unreachable!("unexpected region in param-env clause") } diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index e66aa6bc4a9ea..fa9d617604e50 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -578,10 +578,15 @@ fn report_conflicting_impls<'tcx>( let lint = match kind { FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK, }; - tcx.node_span_lint(lint, tcx.local_def_id_to_hir_id(impl_def_id), impl_span, |err| { - err.primary_message(msg()); - decorate(tcx, &overlap, impl_span, err); - }); + tcx.emit_node_span_lint( + lint, + tcx.local_def_id_to_hir_id(impl_def_id), + impl_span, + rustc_errors::DiagDecorator(|err| { + err.primary_message(msg()); + decorate(tcx, &overlap, impl_span, err); + }), + ); Ok(()) } } diff --git a/library/std/src/sys/env/wasi.rs b/library/std/src/sys/env/wasi.rs index c970aac182604..6b892376fd0cf 100644 --- a/library/std/src/sys/env/wasi.rs +++ b/library/std/src/sys/env/wasi.rs @@ -1,11 +1,16 @@ use core::slice::memchr; pub use super::common::Env; -use crate::ffi::{CStr, OsStr, OsString}; +use crate::ffi::{CStr, OsStr, OsString, c_char}; use crate::io; use crate::os::wasi::prelude::*; use crate::sys::helpers::run_with_cstr; -use crate::sys::pal::os::{cvt, libc}; +use crate::sys::pal::cvt; + +// This is not available yet in libc. +unsafe extern "C" { + fn __wasilibc_get_environ() -> *mut *mut c_char; +} cfg_select! { target_feature = "atomics" => { @@ -37,7 +42,7 @@ pub fn env() -> Env { // Use `__wasilibc_get_environ` instead of `environ` here so that we // don't require wasi-libc to eagerly initialize the environment // variables. - let mut environ = libc::__wasilibc_get_environ(); + let mut environ = __wasilibc_get_environ(); let mut result = Vec::new(); if !environ.is_null() { diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index 5e20c0ffdfa6a..f3c860804de03 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -684,7 +684,7 @@ fn on_resolver_failure() { use crate::sys; // If the version fails to parse, we treat it the same as "not glibc". - if let Some(version) = sys::os::glibc_version() { + if let Some(version) = sys::pal::conf::glibc_version() { if version < (2, 26) { unsafe { libc::res_init() }; } diff --git a/library/std/src/sys/pal/solid/error.rs b/library/std/src/sys/pal/solid/error.rs index 3e85cdb3c1d9f..a737abcc04eda 100644 --- a/library/std/src/sys/pal/solid/error.rs +++ b/library/std/src/sys/pal/solid/error.rs @@ -3,6 +3,14 @@ use super::{abi, itron}; use crate::io; use crate::sys::net; +// SOLID directly maps `errno`s to μITRON error codes. +impl SolidError { + #[inline] + pub(crate) fn as_io_error(self) -> crate::io::Error { + crate::io::Error::from_raw_os_error(self.as_raw()) + } +} + /// Describe the specified SOLID error code. Returns `None` if it's an /// undefined error code. /// diff --git a/library/std/src/sys/pal/solid/os.rs b/library/std/src/sys/pal/solid/os.rs index 4a07d240d2e66..79bb91b179969 100644 --- a/library/std/src/sys/pal/solid/os.rs +++ b/library/std/src/sys/pal/solid/os.rs @@ -1,16 +1,8 @@ -use super::{itron, unsupported}; +use super::unsupported; use crate::ffi::{OsStr, OsString}; use crate::path::{self, PathBuf}; use crate::{fmt, io}; -// `solid` directly maps `errno`s to μITRON error codes. -impl itron::error::ItronError { - #[inline] - pub(crate) fn as_io_error(self) -> crate::io::Error { - crate::io::Error::from_raw_os_error(self.as_raw()) - } -} - pub fn getcwd() -> io::Result { unsupported() } diff --git a/library/std/src/sys/pal/teeos/conf.rs b/library/std/src/sys/pal/teeos/conf.rs new file mode 100644 index 0000000000000..1d13a283c458b --- /dev/null +++ b/library/std/src/sys/pal/teeos/conf.rs @@ -0,0 +1,5 @@ +// Hardcoded to return 4096, since `sysconf` is only implemented as a stub. +pub fn page_size() -> usize { + // unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }; + 4096 +} diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index f76c26d3c966c..7d2ecdbf7ec4b 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -6,6 +6,7 @@ #![allow(unused_variables)] #![allow(dead_code)] +pub mod conf; pub mod os; #[path = "../unix/time.rs"] pub mod time; diff --git a/library/std/src/sys/pal/teeos/os.rs b/library/std/src/sys/pal/teeos/os.rs index c09b84f42bab9..c86fa555e4117 100644 --- a/library/std/src/sys/pal/teeos/os.rs +++ b/library/std/src/sys/pal/teeos/os.rs @@ -7,12 +7,6 @@ use crate::ffi::{OsStr, OsString}; use crate::path::PathBuf; use crate::{fmt, io, path}; -// Hardcoded to return 4096, since `sysconf` is only implemented as a stub. -pub fn page_size() -> usize { - // unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }; - 4096 -} - // Everything below are stubs and copied from unsupported.rs pub fn getcwd() -> io::Result { diff --git a/library/std/src/sys/pal/unix/conf.rs b/library/std/src/sys/pal/unix/conf.rs new file mode 100644 index 0000000000000..a97173a1a35a1 --- /dev/null +++ b/library/std/src/sys/pal/unix/conf.rs @@ -0,0 +1,97 @@ +#[cfg(test)] +mod tests; + +#[cfg(not(target_os = "espidf"))] +pub fn page_size() -> usize { + unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize } +} + +/// Returns the value for [`confstr(key, ...)`][posix_confstr]. Currently only +/// used on Darwin, but should work on any unix (in case we need to get +/// `_CS_PATH` or `_CS_V[67]_ENV` in the future). +/// +/// [posix_confstr]: +/// https://pubs.opengroup.org/onlinepubs/9699919799/functions/confstr.html +// +// FIXME: Support `confstr` in Miri. +#[cfg(all(target_vendor = "apple", not(miri)))] +pub fn confstr( + key: crate::ffi::c_int, + size_hint: Option, +) -> crate::io::Result { + use crate::ffi::OsString; + use crate::io; + use crate::os::unix::ffi::OsStringExt; + + let mut buf: Vec = Vec::with_capacity(0); + let mut bytes_needed_including_nul = size_hint + .unwrap_or_else(|| { + // Treat "None" as "do an extra call to get the length". In theory + // we could move this into the loop below, but it's hard to do given + // that it isn't 100% clear if it's legal to pass 0 for `len` when + // the buffer isn't null. + unsafe { libc::confstr(key, core::ptr::null_mut(), 0) } + }) + .max(1); + // If the value returned by `confstr` is greater than the len passed into + // it, then the value was truncated, meaning we need to retry. Note that + // while `confstr` results don't seem to change for a process, it's unclear + // if this is guaranteed anywhere, so looping does seem required. + while bytes_needed_including_nul > buf.capacity() { + // We write into the spare capacity of `buf`. This lets us avoid + // changing buf's `len`, which both simplifies `reserve` computation, + // allows working with `Vec` instead of `Vec>`, and + // may avoid a copy, since the Vec knows that none of the bytes are needed + // when reallocating (well, in theory anyway). + buf.reserve(bytes_needed_including_nul); + // `confstr` returns + // - 0 in the case of errors: we break and return an error. + // - The number of bytes written, iff the provided buffer is enough to + // hold the entire value: we break and return the data in `buf`. + // - Otherwise, the number of bytes needed (including nul): we go + // through the loop again. + bytes_needed_including_nul = + unsafe { libc::confstr(key, buf.as_mut_ptr().cast(), buf.capacity()) }; + } + // `confstr` returns 0 in the case of an error. + if bytes_needed_including_nul == 0 { + return Err(io::Error::last_os_error()); + } + // Safety: `confstr(..., buf.as_mut_ptr(), buf.capacity())` returned a + // non-zero value, meaning `bytes_needed_including_nul` bytes were + // initialized. + unsafe { + buf.set_len(bytes_needed_including_nul); + // Remove the NUL-terminator. + let last_byte = buf.pop(); + // ... and smoke-check that it *was* a NUL-terminator. + assert_eq!(last_byte, Some(0), "`confstr` provided a string which wasn't nul-terminated"); + }; + Ok(OsString::from_vec(buf)) +} + +#[cfg(all(target_os = "linux", target_env = "gnu"))] +pub fn glibc_version() -> Option<(usize, usize)> { + use crate::ffi::CStr; + + unsafe extern "C" { + fn gnu_get_libc_version() -> *const libc::c_char; + } + let version_cstr = unsafe { CStr::from_ptr(gnu_get_libc_version()) }; + if let Ok(version_str) = version_cstr.to_str() { + parse_glibc_version(version_str) + } else { + None + } +} + +/// Returns Some((major, minor)) if the string is a valid "x.y" version, +/// ignoring any extra dot-separated parts. Otherwise return None. +#[cfg(all(target_os = "linux", target_env = "gnu"))] +fn parse_glibc_version(version: &str) -> Option<(usize, usize)> { + let mut parsed_ints = version.split('.').map(str::parse::).fuse(); + match (parsed_ints.next(), parsed_ints.next()) { + (Some(Ok(major)), Some(Ok(minor))) => Some((major, minor)), + _ => None, + } +} diff --git a/library/std/src/sys/pal/unix/os/tests.rs b/library/std/src/sys/pal/unix/conf/tests.rs similarity index 100% rename from library/std/src/sys/pal/unix/os/tests.rs rename to library/std/src/sys/pal/unix/conf/tests.rs diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 0fbf37fda7fbf..9931b4de0b9bf 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -2,6 +2,7 @@ use crate::io; +pub mod conf; #[cfg(target_os = "fuchsia")] pub mod fuchsia; pub mod futex; diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index d11282682d08d..f69614c2077cd 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -2,9 +2,6 @@ #![allow(unused_imports)] // lots of cfg code here -#[cfg(test)] -mod tests; - use libc::{c_char, c_int, c_void}; use crate::ffi::{CStr, OsStr, OsString}; @@ -396,75 +393,15 @@ pub fn current_exe() -> io::Result { if !path.is_absolute() { getcwd().map(|cwd| cwd.join(path)) } else { Ok(path) } } -#[cfg(not(target_os = "espidf"))] -pub fn page_size() -> usize { - unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize } -} - -// Returns the value for [`confstr(key, ...)`][posix_confstr]. Currently only -// used on Darwin, but should work on any unix (in case we need to get -// `_CS_PATH` or `_CS_V[67]_ENV` in the future). -// -// [posix_confstr]: -// https://pubs.opengroup.org/onlinepubs/9699919799/functions/confstr.html -// -// FIXME: Support `confstr` in Miri. -#[cfg(all(target_vendor = "apple", not(miri)))] -fn confstr(key: c_int, size_hint: Option) -> io::Result { - let mut buf: Vec = Vec::with_capacity(0); - let mut bytes_needed_including_nul = size_hint - .unwrap_or_else(|| { - // Treat "None" as "do an extra call to get the length". In theory - // we could move this into the loop below, but it's hard to do given - // that it isn't 100% clear if it's legal to pass 0 for `len` when - // the buffer isn't null. - unsafe { libc::confstr(key, core::ptr::null_mut(), 0) } - }) - .max(1); - // If the value returned by `confstr` is greater than the len passed into - // it, then the value was truncated, meaning we need to retry. Note that - // while `confstr` results don't seem to change for a process, it's unclear - // if this is guaranteed anywhere, so looping does seem required. - while bytes_needed_including_nul > buf.capacity() { - // We write into the spare capacity of `buf`. This lets us avoid - // changing buf's `len`, which both simplifies `reserve` computation, - // allows working with `Vec` instead of `Vec>`, and - // may avoid a copy, since the Vec knows that none of the bytes are needed - // when reallocating (well, in theory anyway). - buf.reserve(bytes_needed_including_nul); - // `confstr` returns - // - 0 in the case of errors: we break and return an error. - // - The number of bytes written, iff the provided buffer is enough to - // hold the entire value: we break and return the data in `buf`. - // - Otherwise, the number of bytes needed (including nul): we go - // through the loop again. - bytes_needed_including_nul = - unsafe { libc::confstr(key, buf.as_mut_ptr().cast::(), buf.capacity()) }; - } - // `confstr` returns 0 in the case of an error. - if bytes_needed_including_nul == 0 { - return Err(io::Error::last_os_error()); - } - // Safety: `confstr(..., buf.as_mut_ptr(), buf.capacity())` returned a - // non-zero value, meaning `bytes_needed_including_nul` bytes were - // initialized. - unsafe { - buf.set_len(bytes_needed_including_nul); - // Remove the NUL-terminator. - let last_byte = buf.pop(); - // ... and smoke-check that it *was* a NUL-terminator. - assert_eq!(last_byte, Some(0), "`confstr` provided a string which wasn't nul-terminated"); - }; - Ok(OsString::from_vec(buf)) -} - #[cfg(all(target_vendor = "apple", not(miri)))] fn darwin_temp_dir() -> PathBuf { - confstr(libc::_CS_DARWIN_USER_TEMP_DIR, Some(64)).map(PathBuf::from).unwrap_or_else(|_| { - // It failed for whatever reason (there are several possible reasons), - // so return the global one. - PathBuf::from("/tmp") - }) + crate::sys::pal::conf::confstr(libc::_CS_DARWIN_USER_TEMP_DIR, Some(64)) + .map(PathBuf::from) + .unwrap_or_else(|_| { + // It failed for whatever reason (there are several possible reasons), + // so return the global one. + PathBuf::from("/tmp") + }) } pub fn temp_dir() -> PathBuf { @@ -532,27 +469,3 @@ pub fn home_dir() -> Option { } } } - -#[cfg(all(target_os = "linux", target_env = "gnu"))] -pub fn glibc_version() -> Option<(usize, usize)> { - unsafe extern "C" { - fn gnu_get_libc_version() -> *const libc::c_char; - } - let version_cstr = unsafe { CStr::from_ptr(gnu_get_libc_version()) }; - if let Ok(version_str) = version_cstr.to_str() { - parse_glibc_version(version_str) - } else { - None - } -} - -// Returns Some((major, minor)) if the string is a valid "x.y" version, -// ignoring any extra dot-separated parts. Otherwise return None. -#[cfg(all(target_os = "linux", target_env = "gnu"))] -fn parse_glibc_version(version: &str) -> Option<(usize, usize)> { - let mut parsed_ints = version.split('.').map(str::parse::).fuse(); - match (parsed_ints.next(), parsed_ints.next()) { - (Some(Ok(major)), Some(Ok(minor))) => Some((major, minor)), - _ => None, - } -} diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs index 040fda75a5080..632f619655b37 100644 --- a/library/std/src/sys/pal/unix/stack_overflow.rs +++ b/library/std/src/sys/pal/unix/stack_overflow.rs @@ -70,7 +70,7 @@ mod imp { use super::thread_info::{delete_current_info, set_current_info, with_current_info}; use crate::ops::Range; use crate::sync::atomic::{Atomic, AtomicBool, AtomicPtr, AtomicUsize, Ordering}; - use crate::sys::pal::unix::os; + use crate::sys::pal::unix::conf; use crate::{io, mem, ptr}; // Signal handler for the SIGSEGV and SIGBUS handlers. We've got guard pages @@ -150,7 +150,7 @@ mod imp { /// Must be called only once #[forbid(unsafe_op_in_unsafe_fn)] pub unsafe fn init() { - PAGE_SIZE.store(os::page_size(), Ordering::Relaxed); + PAGE_SIZE.store(conf::page_size(), Ordering::Relaxed); let mut guard_page_range = unsafe { install_main_guard() }; diff --git a/library/std/src/sys/pal/wasi/conf.rs b/library/std/src/sys/pal/wasi/conf.rs new file mode 100644 index 0000000000000..cf76ae733358e --- /dev/null +++ b/library/std/src/sys/pal/wasi/conf.rs @@ -0,0 +1,4 @@ +#[allow(dead_code)] +pub fn page_size() -> usize { + unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize } +} diff --git a/library/std/src/sys/pal/wasi/helpers.rs b/library/std/src/sys/pal/wasi/helpers.rs deleted file mode 100644 index 4f2eb1148f0b3..0000000000000 --- a/library/std/src/sys/pal/wasi/helpers.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![forbid(unsafe_op_in_unsafe_fn)] - -pub fn abort_internal() -> ! { - unsafe { libc::abort() } -} - -#[inline] -#[cfg(target_env = "p1")] -pub(crate) fn err2io(err: wasi::Errno) -> crate::io::Error { - crate::io::Error::from_raw_os_error(err.raw().into()) -} diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs index 9b49db9af6b05..66d91078a5d54 100644 --- a/library/std/src/sys/pal/wasi/mod.rs +++ b/library/std/src/sys/pal/wasi/mod.rs @@ -4,34 +4,64 @@ //! OS level functionality for WASI. Currently this includes both WASIp1 and //! WASIp2. +use crate::io; + +pub mod conf; #[allow(unused)] #[path = "../wasm/atomics/futex.rs"] pub mod futex; - pub mod os; pub mod stack_overflow; #[path = "../unix/time.rs"] pub mod time; +#[cfg(not(target_env = "p1"))] +mod cabi_realloc; + #[path = "../unsupported/common.rs"] #[deny(unsafe_op_in_unsafe_fn)] -#[allow(unused)] +#[expect(dead_code)] mod common; +pub use common::{cleanup, init, unsupported}; -pub use common::*; +pub fn abort_internal() -> ! { + unsafe { libc::abort() } +} -mod helpers; +#[inline] +#[cfg(target_env = "p1")] +pub(crate) fn err2io(err: wasi::Errno) -> crate::io::Error { + crate::io::Error::from_raw_os_error(err.raw().into()) +} -// The following exports are listed individually to work around Rust's glob -// import conflict rules. If we glob export `helpers` and `common` together, -// then the compiler complains about conflicts. +#[doc(hidden)] +pub trait IsMinusOne { + fn is_minus_one(&self) -> bool; +} -pub(crate) use helpers::abort_internal; -#[cfg(target_env = "p1")] -pub(crate) use helpers::err2io; -#[cfg(not(target_env = "p1"))] -pub use os::IsMinusOne; -pub use os::{cvt, cvt_r}; +macro_rules! impl_is_minus_one { + ($($t:ident)*) => ($(impl IsMinusOne for $t { + fn is_minus_one(&self) -> bool { + *self == -1 + } + })*) +} -#[cfg(not(target_env = "p1"))] -mod cabi_realloc; +impl_is_minus_one! { i8 i16 i32 i64 isize } + +pub fn cvt(t: T) -> io::Result { + if t.is_minus_one() { Err(io::Error::last_os_error()) } else { Ok(t) } +} + +pub fn cvt_r(mut f: F) -> io::Result +where + T: IsMinusOne, + F: FnMut() -> T, +{ + loop { + match cvt(f()) { + Err(ref e) if e.is_interrupted() => {} + other => return other, + } + } +} diff --git a/library/std/src/sys/pal/wasi/os.rs b/library/std/src/sys/pal/wasi/os.rs index c8f3ddf692bcc..b1c26acc68cb9 100644 --- a/library/std/src/sys/pal/wasi/os.rs +++ b/library/std/src/sys/pal/wasi/os.rs @@ -8,17 +8,6 @@ use crate::sys::helpers::run_path_with_cstr; use crate::sys::unsupported; use crate::{fmt, io}; -// Add a few symbols not in upstream `libc` just yet. -pub mod libc { - pub use libc::*; - - unsafe extern "C" { - pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char; - pub fn chdir(dir: *const c_char) -> c_int; - pub fn __wasilibc_get_environ() -> *mut *mut c_char; - } -} - pub fn getcwd() -> io::Result { let mut buf = Vec::with_capacity(512); loop { @@ -89,11 +78,6 @@ pub fn current_exe() -> io::Result { unsupported() } -#[allow(dead_code)] -pub fn page_size() -> usize { - unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize } -} - pub fn temp_dir() -> PathBuf { panic!("no filesystem on wasm") } @@ -101,35 +85,3 @@ pub fn temp_dir() -> PathBuf { pub fn home_dir() -> Option { None } - -#[doc(hidden)] -pub trait IsMinusOne { - fn is_minus_one(&self) -> bool; -} - -macro_rules! impl_is_minus_one { - ($($t:ident)*) => ($(impl IsMinusOne for $t { - fn is_minus_one(&self) -> bool { - *self == -1 - } - })*) -} - -impl_is_minus_one! { i8 i16 i32 i64 isize } - -pub fn cvt(t: T) -> io::Result { - if t.is_minus_one() { Err(io::Error::last_os_error()) } else { Ok(t) } -} - -pub fn cvt_r(mut f: F) -> io::Result -where - T: IsMinusOne, - F: FnMut() -> T, -{ - loop { - match cvt(f()) { - Err(ref e) if e.is_interrupted() => {} - other => return other, - } - } -} diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index 82ff94fb1e030..a68be2543bc23 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -537,7 +537,7 @@ impl Command { // Only glibc 2.24+ posix_spawn() supports returning ENOENT directly. #[cfg(all(target_os = "linux", target_env = "gnu"))] { - if let Some(version) = sys::os::glibc_version() { + if let Some(version) = sys::pal::conf::glibc_version() { if version < (2, 24) { return Ok(None); } diff --git a/library/std/src/sys/thread/teeos.rs b/library/std/src/sys/thread/teeos.rs index 5e71f757eaa4b..aa679e780c18c 100644 --- a/library/std/src/sys/thread/teeos.rs +++ b/library/std/src/sys/thread/teeos.rs @@ -1,5 +1,5 @@ use crate::mem::{self, ManuallyDrop}; -use crate::sys::os; +use crate::sys::pal::conf; use crate::thread::ThreadInit; use crate::time::Duration; use crate::{cmp, io, ptr}; @@ -52,7 +52,7 @@ impl Thread { // multiple of the system page size. Because it's definitely // >= PTHREAD_STACK_MIN, it must be an alignment issue. // Round up to the nearest page and try again. - let page_size = os::page_size(); + let page_size = conf::page_size(); let stack_size = (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1); assert_eq!(unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) }, 0); diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index 22f9bfef5a383..5d4eabc226ed7 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs @@ -76,7 +76,7 @@ impl Thread { // multiple of the system page size. Because it's definitely // >= PTHREAD_STACK_MIN, it must be an alignment issue. // Round up to the nearest page and try again. - let page_size = sys::os::page_size(); + let page_size = sys::pal::conf::page_size(); let stack_size = (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1); diff --git a/rustfmt.toml b/rustfmt.toml index 910eea1037986..4750b8541457c 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -55,8 +55,4 @@ ignore = [ # Code automatically generated and included. "compiler/rustc_codegen_gcc/src/intrinsic/archs.rs", "compiler/rustc_codegen_gcc/example", - - # Rustfmt doesn't support use closures yet - "tests/mir-opt/ergonomic-clones/closure.rs", - "tests/codegen-llvm/ergonomic-clones/closure.rs", ] diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 7dfd566a58ccb..f4e6a20ec8497 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -607,6 +607,7 @@ Select which editor you would like to set up [default: None]: "; "1c43ead340b20792b91d02b08494ee68708e7e09f56b6766629b4b72079208f1", "eec09a09452682060afd23dd5d3536ccac5615b3cdbf427366446901215fb9f6", "cb653043852d9d5ff4a5be56407b859ff9928be055ad3f307eb309aad04765e6", + "e28b1930d16d3d8bbdeed7bd4a995613e648b49e08c9b6f5271880f520637fed", ], EditorKind::Vim | EditorKind::VsCode => &[ "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8", @@ -626,6 +627,7 @@ Select which editor you would like to set up [default: None]: "; "02a49ac2d31f00ef6e4531c44e00dac51cea895112e480553f1ba060b3942a47", "0aa4748848de0d1cb7ece92a0123c8897fef6de2f58aff8fda1426f098b7a798", "e5e357862e5d6d0d9da335e9823c07b8a7dc42bbf18d72cc5206ad1049cd8fcc", + "a68fd5828e75f3e921f265e29ce1e9efa554083c3773fdb4b8e1ab3b2d9dc6cd", ], EditorKind::Zed => &[ "bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c", @@ -636,6 +638,7 @@ Select which editor you would like to set up [default: None]: "; "5ef83292111d9a8bb63b6afc3abf42d0bc78fe24985f0d2e039e73258b5dab8f", "74420c13094b530a986b37c4f1d23cb58c0e8e2295f5858ded129fb1574e66f9", "2d3b592c089b2ad2c528686a1e371af49922edad1c59accd5d5f31612a441568", + "0767a2398ccc253274b184adbb9e018ce931bd0ef45baad06dad19b652c52951", ], } } diff --git a/src/ci/docker/host-x86_64/dist-ohos-aarch64/Dockerfile b/src/ci/docker/host-x86_64/dist-ohos-aarch64/Dockerfile index adeaf809f4208..f97092e9dd1f5 100644 --- a/src/ci/docker/host-x86_64/dist-ohos-aarch64/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-ohos-aarch64/Dockerfile @@ -40,14 +40,13 @@ ENV \ AR_aarch64_unknown_linux_ohos=/opt/ohos-sdk/native/llvm/bin/llvm-ar \ CXX_aarch64_unknown_linux_ohos=/usr/local/bin/aarch64-unknown-linux-ohos-clang++.sh -ENV RUST_CONFIGURE_ARGS \ - --enable-profiler \ +ENV RUST_CONFIGURE_ARGS="--enable-profiler \ --disable-docs \ --tools=cargo,clippy,rustdocs,rustfmt,rust-analyzer,rust-analyzer-proc-macro-srv,analysis,src,wasm-component-ld \ --enable-extended \ - --enable-sanitizers + --enable-sanitizers" -ENV SCRIPT python3 ../x.py dist --host=$TARGETS --target $TARGETS +ENV SCRIPT="python3 ../x.py dist --host=$TARGETS --target $TARGETS" COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/dist-ohos-x86_64/Dockerfile b/src/ci/docker/host-x86_64/dist-ohos-x86_64/Dockerfile index 98e402adf2a69..e3352e52d691b 100644 --- a/src/ci/docker/host-x86_64/dist-ohos-x86_64/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-ohos-x86_64/Dockerfile @@ -40,14 +40,13 @@ ENV \ AR_x86_64_unknown_linux_ohos=/opt/ohos-sdk/native/llvm/bin/llvm-ar \ CXX_x86_64_unknown_linux_ohos=/usr/local/bin/x86_64-unknown-linux-ohos-clang++.sh -ENV RUST_CONFIGURE_ARGS \ - --enable-profiler \ +ENV RUST_CONFIGURE_ARGS="--enable-profiler \ --disable-docs \ --tools=cargo,clippy,rustdocs,rustfmt,rust-analyzer,rust-analyzer-proc-macro-srv,analysis,src,wasm-component-ld \ --enable-extended \ - --enable-sanitizers + --enable-sanitizers" -ENV SCRIPT python3 ../x.py dist --host=$TARGETS --target $TARGETS +ENV SCRIPT="python3 ../x.py dist --host=$TARGETS --target $TARGETS" COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/etc/rust_analyzer_helix.toml b/src/etc/rust_analyzer_helix.toml index c9ee1ca181d50..ae2c2d9064886 100644 --- a/src/etc/rust_analyzer_helix.toml +++ b/src/etc/rust_analyzer_helix.toml @@ -9,6 +9,9 @@ # x fmt --check # ``` # (if that doesn't work -- do `x clean` first) +# +# NOTE: helix doesn't support getting workspace root in configs, for this config +# to work replace WORKSPACE_ROOT with the path to your rustc checkout [language-server.rust-analyzer.config] linkedProjects = [ @@ -33,7 +36,7 @@ overrideCommand = [ [language-server.rust-analyzer.config.rustfmt] overrideCommand = [ - "build/host/rustfmt/bin/rustfmt", + "WORKSPACE_ROOT/build/host/rustfmt/bin/rustfmt", "--edition=2024" ] @@ -64,7 +67,8 @@ overrideCommand = [ ] [language-server.rust-analyzer.environment] -RUSTUP_TOOLCHAIN = "nightly" +RUSTC = "WORKSPACE_ROOT/build/host/stage0/bin/rustc" +CARGO = "WORKSPACE_ROOT/build/host/stage0/bin/cargo" [[language]] name = "rust" diff --git a/src/etc/rust_analyzer_settings.json b/src/etc/rust_analyzer_settings.json index 8e94fbaa163e8..ea5bb544c7004 100644 --- a/src/etc/rust_analyzer_settings.json +++ b/src/etc/rust_analyzer_settings.json @@ -1,3 +1,14 @@ +// This config uses a separate build directory for rust-analyzer, +// so that r-a's checks don't block user `x` commands and vice-verse. +// R-a's build directory is located in `build-rust-analyzer`. +// +// To download rustfmt and proc macro server for r-a run the following command +// (proc macro server is downloaded automatically with pretty much any command, +// this specific one also downloads rustfmt): +// ``` +// x fmt --check +// ``` +// (if that doesn't work -- do `x clean` first) { "git.detectSubmodulesLimit": 20, "rust-analyzer.linkedProjects": [ @@ -40,7 +51,8 @@ "build-rust-analyzer" ], "rust-analyzer.server.extraEnv": { - "RUSTUP_TOOLCHAIN": "nightly" + "RUSTC": "${workspaceFolder}/build/host/stage0/bin/rustc", + "CARGO": "${workspaceFolder}/build/host/stage0/bin/cargo" }, "files.associations": { "*.fixed": "rust", diff --git a/src/etc/rust_analyzer_zed.json b/src/etc/rust_analyzer_zed.json index df1f7334556c3..e69800c0624d9 100644 --- a/src/etc/rust_analyzer_zed.json +++ b/src/etc/rust_analyzer_zed.json @@ -1,3 +1,14 @@ +// This config uses a separate build directory for rust-analyzer, +// so that r-a's checks don't block user `x` commands and vice-verse. +// R-a's build directory is located in `build-rust-analyzer`. +// +// To download rustfmt and proc macro server for r-a run the following command +// (proc macro server is downloaded automatically with pretty much any command, +// this specific one also downloads rustfmt): +// ``` +// x fmt --check +// ``` +// (if that doesn't work -- do `x clean` first) { "lsp": { "rust-analyzer": { @@ -55,7 +66,8 @@ }, "server": { "extraEnv": { - "RUSTUP_TOOLCHAIN": "nightly" + "RUSTC": "build/host/stage0/bin/rustc", + "CARGO": "build/host/stage0/bin/cargo" } } } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index c472c20a7dc71..2171ca9897799 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -799,14 +799,7 @@ impl<'tcx> ExtraInfo<'tcx> { } fn error_invalid_codeblock_attr(&self, msg: impl Into) { - self.tcx.node_span_lint( - crate::lint::INVALID_CODEBLOCK_ATTRIBUTES, - self.tcx.local_def_id_to_hir_id(self.def_id), - self.sp, - |lint| { - lint.primary_message(msg); - }, - ); + self.error_invalid_codeblock_attr_with_help(msg, |_| {}); } fn error_invalid_codeblock_attr_with_help( @@ -814,14 +807,14 @@ impl<'tcx> ExtraInfo<'tcx> { msg: impl Into, f: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ) { - self.tcx.node_span_lint( + self.tcx.emit_node_span_lint( crate::lint::INVALID_CODEBLOCK_ATTRIBUTES, self.tcx.local_def_id_to_hir_id(self.def_id), self.sp, - |lint| { + rustc_errors::DiagDecorator(|lint| { lint.primary_message(msg); f(lint); - }, + }), ); } } diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index 39116061f4854..40dfdb890d66f 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -6,6 +6,7 @@ //! - PRIVATE_DOC_TESTS: this lint is **STABLE** and looks for private items with doctests. use rustc_hir as hir; +use rustc_macros::Diagnostic; use rustc_middle::lint::{LevelAndSource, LintLevelSource}; use rustc_session::lint; use tracing::debug; @@ -116,6 +117,14 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) - } pub(crate) fn look_for_tests(cx: &DocContext<'_>, dox: &str, item: &Item) { + #[derive(Diagnostic)] + #[diag("missing code example in this documentation")] + struct MissingCodeExample; + + #[derive(Diagnostic)] + #[diag("documentation test in private item")] + struct DoctestInPrivateItem; + let Some(hir_id) = DocContext::as_local_hir_id(cx.tcx, item.item_id) else { // If non-local, no need to check anything. return; @@ -129,20 +138,21 @@ pub(crate) fn look_for_tests(cx: &DocContext<'_>, dox: &str, item: &Item) { if should_have_doc_example(cx, item) { debug!("reporting error for {item:?} (hir_id={hir_id:?})"); let sp = item.attr_span(cx.tcx); - cx.tcx.node_span_lint(crate::lint::MISSING_DOC_CODE_EXAMPLES, hir_id, sp, |lint| { - lint.primary_message("missing code example in this documentation"); - }); + cx.tcx.emit_node_span_lint( + crate::lint::MISSING_DOC_CODE_EXAMPLES, + hir_id, + sp, + MissingCodeExample, + ); } } else if tests.found_tests > 0 && !cx.cache.effective_visibilities.is_exported(cx.tcx, item.item_id.expect_def_id()) { - cx.tcx.node_span_lint( + cx.tcx.emit_node_span_lint( crate::lint::PRIVATE_DOC_TESTS, hir_id, item.attr_span(cx.tcx), - |lint| { - lint.primary_message("documentation test in private item"); - }, + DoctestInPrivateItem, ); } } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 697b35ad8e85b..3e68ed950ce16 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1914,61 +1914,70 @@ fn report_diagnostic( let sp = item.attr_span(tcx); - tcx.node_span_lint(lint, hir_id, sp, |lint| { - lint.primary_message(msg); - - let (span, link_range) = match link_range { - MarkdownLinkRange::Destination(md_range) => { - let mut md_range = md_range.clone(); - let sp = - source_span_for_markdown_range(tcx, dox, &md_range, &item.attrs.doc_strings) - .map(|(mut sp, _)| { - while dox.as_bytes().get(md_range.start) == Some(&b' ') - || dox.as_bytes().get(md_range.start) == Some(&b'`') - { - md_range.start += 1; - sp = sp.with_lo(sp.lo() + BytePos(1)); - } - while dox.as_bytes().get(md_range.end - 1) == Some(&b' ') - || dox.as_bytes().get(md_range.end - 1) == Some(&b'`') - { - md_range.end -= 1; - sp = sp.with_hi(sp.hi() - BytePos(1)); - } - sp - }); - (sp, MarkdownLinkRange::Destination(md_range)) - } - MarkdownLinkRange::WholeLink(md_range) => ( - source_span_for_markdown_range(tcx, dox, md_range, &item.attrs.doc_strings) - .map(|(sp, _)| sp), - link_range.clone(), - ), - }; + tcx.emit_node_span_lint( + lint, + hir_id, + sp, + rustc_errors::DiagDecorator(|lint| { + lint.primary_message(msg); + + let (span, link_range) = match link_range { + MarkdownLinkRange::Destination(md_range) => { + let mut md_range = md_range.clone(); + let sp = source_span_for_markdown_range( + tcx, + dox, + &md_range, + &item.attrs.doc_strings, + ) + .map(|(mut sp, _)| { + while dox.as_bytes().get(md_range.start) == Some(&b' ') + || dox.as_bytes().get(md_range.start) == Some(&b'`') + { + md_range.start += 1; + sp = sp.with_lo(sp.lo() + BytePos(1)); + } + while dox.as_bytes().get(md_range.end - 1) == Some(&b' ') + || dox.as_bytes().get(md_range.end - 1) == Some(&b'`') + { + md_range.end -= 1; + sp = sp.with_hi(sp.hi() - BytePos(1)); + } + sp + }); + (sp, MarkdownLinkRange::Destination(md_range)) + } + MarkdownLinkRange::WholeLink(md_range) => ( + source_span_for_markdown_range(tcx, dox, md_range, &item.attrs.doc_strings) + .map(|(sp, _)| sp), + link_range.clone(), + ), + }; - if let Some(sp) = span { - lint.span(sp); - } else { - // blah blah blah\nblah\nblah [blah] blah blah\nblah blah - // ^ ~~~~ - // | link_range - // last_new_line_offset - let md_range = link_range.inner_range().clone(); - let last_new_line_offset = dox[..md_range.start].rfind('\n').map_or(0, |n| n + 1); - let line = dox[last_new_line_offset..].lines().next().unwrap_or(""); - - // Print the line containing the `md_range` and manually mark it with '^'s. - lint.note(format!( - "the link appears in this line:\n\n{line}\n\ + if let Some(sp) = span { + lint.span(sp); + } else { + // blah blah blah\nblah\nblah [blah] blah blah\nblah blah + // ^ ~~~~ + // | link_range + // last_new_line_offset + let md_range = link_range.inner_range().clone(); + let last_new_line_offset = dox[..md_range.start].rfind('\n').map_or(0, |n| n + 1); + let line = dox[last_new_line_offset..].lines().next().unwrap_or(""); + + // Print the line containing the `md_range` and manually mark it with '^'s. + lint.note(format!( + "the link appears in this line:\n\n{line}\n\ {indicator: { + buffer: &'a Buffer, + code_block: RustCodeBlock, + span: Span, + is_precise_span: bool, + } + + impl<'a, 'b> Diagnostic<'a, ()> for CodeblockError<'b> { + fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { + let Self { buffer, code_block, span, is_precise_span } = self; + + let mut lint = Diag::new( + dcx, + level, + if buffer.has_errors { + "could not parse code block as Rust code" + } else { + "Rust code block is empty" + }, + ); + + let empty_block = code_block.lang_string == Default::default() && code_block.is_fenced; + let is_ignore = code_block.lang_string.ignore != markdown::Ignore::None; + + let explanation = if is_ignore { + "`ignore` code blocks require valid Rust code for syntax highlighting; \ + mark blocks that do not contain Rust code as text" + } else { + "mark blocks that do not contain Rust code as text" + }; + + if is_precise_span { + if is_ignore { + // Giving an accurate suggestion is hard because `ignore` might not have come + // first in the list. Just give a `help` instead. + lint.span_help( + span.from_inner(InnerSpan::new(0, 3)), + format!("{explanation}: ```text"), + ); + } else if empty_block { + lint.span_suggestion( + span.from_inner(InnerSpan::new(0, 3)).shrink_to_hi(), + explanation, + "text", + Applicability::MachineApplicable, + ); + } + } else if empty_block || is_ignore { + lint.help(format!("{explanation}: ```text")); + } + + // FIXME(#67563): Provide more context for these errors by displaying the spans inline. + for message in buffer.messages.iter() { + lint.note(message.clone()); + } + + lint + } + } + let buffer = Arc::new(Lock::new(Buffer::default())); let emitter = BufferEmitter { buffer: Arc::clone(&buffer) }; let sm = Arc::new(SourceMap::new(FilePathMapping::empty())); let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings(); - let source = dox[code_block.code] + let source = dox[code_block.code.clone()] .lines() .map(|line| crate::html::markdown::map_line(line).for_code()) .intersperse(Cow::Borrowed("\n")) @@ -75,11 +135,8 @@ fn check_rust_syntax( return; }; - let empty_block = code_block.lang_string == Default::default() && code_block.is_fenced; - let is_ignore = code_block.lang_string.ignore != markdown::Ignore::None; - // The span and whether it is precise or not. - let (sp, precise_span) = match source_span_for_markdown_range( + let (span, is_precise_span) = match source_span_for_markdown_range( cx.tcx, dox, &code_block.range, @@ -89,51 +146,16 @@ fn check_rust_syntax( None => (item.attr_span(cx.tcx), false), }; - let msg = if buffer.has_errors { - "could not parse code block as Rust code" - } else { - "Rust code block is empty" - }; - // Finally build and emit the completed diagnostic. // All points of divergence have been handled earlier so this can be // done the same way whether the span is precise or not. let hir_id = cx.tcx.local_def_id_to_hir_id(local_id); - cx.tcx.node_span_lint(crate::lint::INVALID_RUST_CODEBLOCKS, hir_id, sp, |lint| { - lint.primary_message(msg); - - let explanation = if is_ignore { - "`ignore` code blocks require valid Rust code for syntax highlighting; \ - mark blocks that do not contain Rust code as text" - } else { - "mark blocks that do not contain Rust code as text" - }; - - if precise_span { - if is_ignore { - // giving an accurate suggestion is hard because `ignore` might not have come first in the list. - // just give a `help` instead. - lint.span_help( - sp.from_inner(InnerSpan::new(0, 3)), - format!("{explanation}: ```text"), - ); - } else if empty_block { - lint.span_suggestion( - sp.from_inner(InnerSpan::new(0, 3)).shrink_to_hi(), - explanation, - "text", - Applicability::MachineApplicable, - ); - } - } else if empty_block || is_ignore { - lint.help(format!("{explanation}: ```text")); - } - - // FIXME(#67563): Provide more context for these errors by displaying the spans inline. - for message in buffer.messages.iter() { - lint.note(message.clone()); - } - }); + cx.tcx.emit_node_span_lint( + crate::lint::INVALID_RUST_CODEBLOCKS, + hir_id, + span, + CodeblockError { buffer: &buffer, code_block, span, is_precise_span }, + ); } #[derive(Default)] diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs index 4e374fe3cd56a..86b8e7b6f86aa 100644 --- a/src/librustdoc/passes/lint/html_tags.rs +++ b/src/librustdoc/passes/lint/html_tags.rs @@ -21,86 +21,91 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & Some((sp, _)) => sp, None => item.attr_span(tcx), }; - tcx.node_span_lint(crate::lint::INVALID_HTML_TAGS, hir_id, sp, |lint| { - use rustc_lint_defs::Applicability; + tcx.emit_node_span_lint( + crate::lint::INVALID_HTML_TAGS, + hir_id, + sp, + rustc_errors::DiagDecorator(|lint| { + use rustc_lint_defs::Applicability; - lint.primary_message(msg); + lint.primary_message(msg); - // If a tag looks like ``, it might actually be a generic. - // We don't try to detect stuff `` because that's not valid HTML, - // and we don't try to detect stuff `` because that's not valid Rust. - let mut generics_end = range.end; - if is_open_tag - && dox[..generics_end].ends_with('>') - && let Some(mut generics_start) = extract_path_backwards(dox, range.start) - { - while generics_start != 0 - && generics_end < dox.len() - && dox.as_bytes()[generics_start - 1] == b'<' - && dox.as_bytes()[generics_end] == b'>' + // If a tag looks like ``, it might actually be a generic. + // We don't try to detect stuff `` because that's not valid HTML, + // and we don't try to detect stuff `` because that's not valid Rust. + let mut generics_end = range.end; + if is_open_tag + && dox[..generics_end].ends_with('>') + && let Some(mut generics_start) = extract_path_backwards(dox, range.start) { - generics_end += 1; - generics_start -= 1; - if let Some(new_start) = extract_path_backwards(dox, generics_start) { - generics_start = new_start; + while generics_start != 0 + && generics_end < dox.len() + && dox.as_bytes()[generics_start - 1] == b'<' + && dox.as_bytes()[generics_end] == b'>' + { + generics_end += 1; + generics_start -= 1; + if let Some(new_start) = extract_path_backwards(dox, generics_start) { + generics_start = new_start; + } + if let Some(new_end) = extract_path_forward(dox, generics_end) { + generics_end = new_end; + } } if let Some(new_end) = extract_path_forward(dox, generics_end) { generics_end = new_end; } + let generics_sp = match source_span_for_markdown_range( + tcx, + dox, + &(generics_start..generics_end), + &item.attrs.doc_strings, + ) { + Some((sp, _)) => sp, + None => item.attr_span(tcx), + }; + // Sometimes, we only extract part of a path. For example, consider this: + // + // <[u32] as IntoIter>::Item + // ^^^^^ unclosed HTML tag `u32` + // + // We don't have any code for parsing fully-qualified trait paths. + // In theory, we could add it, but doing it correctly would require + // parsing the entire path grammar, which is problematic because of + // overlap between the path grammar and Markdown. + // + // The example above shows that ambiguity. Is `[u32]` intended to be an + // intra-doc link to the u32 primitive, or is it intended to be a slice? + // + // If the below conditional were removed, we would suggest this, which is + // not what the user probably wants. + // + // <[u32] as `IntoIter`>::Item + // + // We know that the user actually wants to wrap the whole thing in a code + // block, but the only reason we know that is because `u32` does not, in + // fact, implement IntoIter. If the example looks like this: + // + // <[Vec] as IntoIter::Item + // + // The ideal fix would be significantly different. + if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<') + || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>') + { + return; + } + // multipart form is chosen here because ``Vec`` would be confusing. + lint.multipart_suggestion( + "try marking as source code", + vec![ + (generics_sp.shrink_to_lo(), String::from("`")), + (generics_sp.shrink_to_hi(), String::from("`")), + ], + Applicability::MaybeIncorrect, + ); } - if let Some(new_end) = extract_path_forward(dox, generics_end) { - generics_end = new_end; - } - let generics_sp = match source_span_for_markdown_range( - tcx, - dox, - &(generics_start..generics_end), - &item.attrs.doc_strings, - ) { - Some((sp, _)) => sp, - None => item.attr_span(tcx), - }; - // Sometimes, we only extract part of a path. For example, consider this: - // - // <[u32] as IntoIter>::Item - // ^^^^^ unclosed HTML tag `u32` - // - // We don't have any code for parsing fully-qualified trait paths. - // In theory, we could add it, but doing it correctly would require - // parsing the entire path grammar, which is problematic because of - // overlap between the path grammar and Markdown. - // - // The example above shows that ambiguity. Is `[u32]` intended to be an - // intra-doc link to the u32 primitive, or is it intended to be a slice? - // - // If the below conditional were removed, we would suggest this, which is - // not what the user probably wants. - // - // <[u32] as `IntoIter`>::Item - // - // We know that the user actually wants to wrap the whole thing in a code - // block, but the only reason we know that is because `u32` does not, in - // fact, implement IntoIter. If the example looks like this: - // - // <[Vec] as IntoIter::Item - // - // The ideal fix would be significantly different. - if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<') - || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>') - { - return; - } - // multipart form is chosen here because ``Vec`` would be confusing. - lint.multipart_suggestion( - "try marking as source code", - vec![ - (generics_sp.shrink_to_lo(), String::from("`")), - (generics_sp.shrink_to_hi(), String::from("`")), - ], - Applicability::MaybeIncorrect, - ); - } - }); + }), + ); }; let mut tagp = TagParser::new(); diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs index e49f54f6df946..84dba5d2f1153 100644 --- a/src/librustdoc/passes/lint/redundant_explicit_links.rs +++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs @@ -1,7 +1,7 @@ use std::ops::Range; use rustc_ast::NodeId; -use rustc_errors::SuggestionStyle; +use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level, SuggestionStyle}; use rustc_hir::HirId; use rustc_hir::def::{DefKind, DocLinkResMap, Namespace, Res}; use rustc_lint_defs::Applicability; @@ -9,8 +9,8 @@ use rustc_resolve::rustdoc::pulldown_cmark::{ BrokenLink, BrokenLinkCallback, CowStr, Event, LinkType, OffsetIter, Parser, Tag, }; use rustc_resolve::rustdoc::{prepare_to_doc_link_resolution, source_span_for_markdown_range}; -use rustc_span::Symbol; use rustc_span::def_id::DefId; +use rustc_span::{Span, Symbol}; use crate::clean::Item; use crate::clean::utils::{find_nearest_parent_module, inherits_doc_hidden}; @@ -154,6 +154,42 @@ fn check_inline_or_reference_unknown_redundancy( link_data: LinkData, (open, close): (u8, u8), ) -> Option<()> { + struct RedundantExplicitLinks { + explicit_span: Span, + display_span: Span, + link_span: Span, + display_link: String, + } + + impl<'a> Diagnostic<'a, ()> for RedundantExplicitLinks { + fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { + let Self { explicit_span, display_span, link_span, display_link } = self; + + let mut diag = Diag::new(dcx, level, "redundant explicit link target") + .with_span_label( + explicit_span, + "explicit target is redundant", + ) + .with_span_label( + display_span, + "because label contains path that resolves to same destination", + ) + .with_note( + "when a link's destination is not specified,\nthe label is used to resolve intra-doc links" + ); + // FIXME (GuillaumeGomez): We cannot use `derive(Diagnostic)` because of this method. + // FIXME2 (GuillaumeGomez): Why isn't there a `with_` equivalent for this method? + diag.span_suggestion_with_style( + link_span, + "remove explicit link target", + format!("[{}]", display_link), + Applicability::MaybeIncorrect, + SuggestionStyle::ShowAlways, + ); + diag + } + } + let (resolvable_link, resolvable_link_range) = (&link_data.resolvable_link?, &link_data.resolvable_link_range?); let (dest_res, display_res) = @@ -192,13 +228,17 @@ fn check_inline_or_reference_unknown_redundancy( return None; }; - cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, |lint| { - lint.primary_message("redundant explicit link target") - .span_label(explicit_span, "explicit target is redundant") - .span_label(display_span, "because label contains path that resolves to same destination") - .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links") - .span_suggestion_with_style(link_span, "remove explicit link target", format!("[{}]", link_data.display_link), Applicability::MaybeIncorrect, SuggestionStyle::ShowAlways); - }); + cx.tcx.emit_node_span_lint( + crate::lint::REDUNDANT_EXPLICIT_LINKS, + hir_id, + explicit_span, + RedundantExplicitLinks { + explicit_span, + display_span, + link_span, + display_link: link_data.display_link, + }, + ); } None @@ -215,6 +255,41 @@ fn check_reference_redundancy( dest: &CowStr<'_>, link_data: LinkData, ) -> Option<()> { + struct RedundantExplicitLinkTarget { + explicit_span: Span, + display_span: Span, + def_span: Span, + link_span: Span, + display_link: String, + } + + impl<'a> Diagnostic<'a, ()> for RedundantExplicitLinkTarget { + fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { + let Self { explicit_span, display_span, def_span, link_span, display_link } = self; + + let mut diag = Diag::new(dcx, level, "redundant explicit link target") + .with_span_label(explicit_span, "explicit target is redundant") + .with_span_label( + display_span, + "because label contains path that resolves to same destination", + ) + .with_span_note(def_span, "referenced explicit link target defined here") + .with_note( + "when a link's destination is not specified,\nthe label is used to resolve intra-doc links" + ); + // FIXME (GuillaumeGomez): We cannot use `derive(Diagnostic)` because of this method. + // FIXME2 (GuillaumeGomez): Why isn't there a `with_` equivalent for this method? + diag.span_suggestion_with_style( + link_span, + "remove explicit link target", + format!("[{}]", display_link), + Applicability::MaybeIncorrect, + SuggestionStyle::ShowAlways, + ); + diag + } + } + let (resolvable_link, resolvable_link_range) = (&link_data.resolvable_link?, &link_data.resolvable_link_range?); let (dest_res, display_res) = @@ -259,14 +334,18 @@ fn check_reference_redundancy( &item.attrs.doc_strings, )?; - cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, |lint| { - lint.primary_message("redundant explicit link target") - .span_label(explicit_span, "explicit target is redundant") - .span_label(display_span, "because label contains path that resolves to same destination") - .span_note(def_span, "referenced explicit link target defined here") - .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links") - .span_suggestion_with_style(link_span, "remove explicit link target", format!("[{}]", link_data.display_link), Applicability::MaybeIncorrect, SuggestionStyle::ShowAlways); - }); + cx.tcx.emit_node_span_lint( + crate::lint::REDUNDANT_EXPLICIT_LINKS, + hir_id, + explicit_span, + RedundantExplicitLinkTarget { + explicit_span, + display_span, + def_span, + link_span, + display_link: link_data.display_link, + }, + ); } None diff --git a/src/librustdoc/passes/lint/unescaped_backticks.rs b/src/librustdoc/passes/lint/unescaped_backticks.rs index b791e024545fd..4c33b82d14b44 100644 --- a/src/librustdoc/passes/lint/unescaped_backticks.rs +++ b/src/librustdoc/passes/lint/unescaped_backticks.rs @@ -52,7 +52,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & None => item.attr_span(tcx), }; - tcx.node_span_lint(crate::lint::UNESCAPED_BACKTICKS, hir_id, span, |lint| { + tcx.emit_node_span_lint(crate::lint::UNESCAPED_BACKTICKS, hir_id, span, rustc_errors::DiagDecorator(|lint| { lint.primary_message("unescaped backtick"); let mut help_emitted = false; @@ -156,7 +156,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: & '\\', "if you meant to use a literal backtick, escape it", ); - }); + })); } Event::Code(_) => { let element = element_stack diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs index c0820e4a6854f..b4d30289cabb9 100644 --- a/src/tools/remote-test-server/src/main.rs +++ b/src/tools/remote-test-server/src/main.rs @@ -123,6 +123,8 @@ fn main() { let listener = bind_socket(config.bind); let (work, tmp): (PathBuf, PathBuf) = if cfg!(target_os = "android") { ("/data/local/tmp/work".into(), "/data/local/tmp/work/tmp".into()) + } else if cfg!(target_os = "uefi") { + ("tmp\\work".into(), "tmp\\work\\tmp".into()) } else { let mut work_dir = env::temp_dir(); work_dir.push("work"); @@ -274,6 +276,8 @@ fn handle_run(socket: TcpStream, work: &Path, tmp: &Path, lock: &Mutex<()>, conf } else if cfg!(target_vendor = "apple") { // On Apple platforms, the environment variable is named differently. "DYLD_LIBRARY_PATH" + } else if cfg!(target_os = "uefi") { + "path" } else { "LD_LIBRARY_PATH" }; diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index d889a1c0c0347..668a8abf1d8bb 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -927,7 +927,6 @@ ui/dst/issue-90528-unsizing-suggestion-3.rs ui/dst/issue-90528-unsizing-suggestion-4.rs ui/dyn-keyword/issue-5153.rs ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs -ui/empty/issue-37026.rs ui/enum-discriminant/auxiliary/issue-41394.rs ui/enum-discriminant/issue-104519.rs ui/enum-discriminant/issue-41394-rpass.rs @@ -1706,9 +1705,6 @@ ui/mismatched_types/issue-47706.rs ui/mismatched_types/issue-74918-missing-lifetime.rs ui/mismatched_types/issue-75361-mismatched-impl.rs ui/mismatched_types/issue-84976.rs -ui/missing-trait-bounds/auxiliary/issue-69725.rs -ui/missing-trait-bounds/issue-35677.rs -ui/missing-trait-bounds/issue-69725.rs ui/modules/auxiliary/issue-13872-1.rs ui/modules/auxiliary/issue-13872-2.rs ui/modules/auxiliary/issue-13872-3.rs @@ -2284,8 +2280,6 @@ ui/recursion/issue-38591-non-regular-dropck-recursion.rs ui/recursion/issue-83150.rs ui/recursion/issue-86784.rs ui/recursion/issue-95134.rs -ui/recursion_limit/issue-105700.rs -ui/recursion_limit/issue-40003.rs ui/regions/issue-101280.rs ui/regions/issue-102374.rs ui/regions/issue-102392.rs diff --git a/tests/codegen-llvm/ergonomic-clones/closure.rs b/tests/codegen-llvm/ergonomic-clones/closure.rs index b6fc81726419a..15a2dd2baebfe 100644 --- a/tests/codegen-llvm/ergonomic-clones/closure.rs +++ b/tests/codegen-llvm/ergonomic-clones/closure.rs @@ -1,7 +1,6 @@ //@ compile-flags: -C no-prepopulate-passes -Copt-level=0 -Zmir-opt-level=0 #![crate_type = "lib"] - #![feature(ergonomic_clones)] #![allow(incomplete_features)] diff --git a/tests/codegen-llvm/inlining-target-feature-differences.rs b/tests/codegen-llvm/inlining-target-feature-differences.rs new file mode 100644 index 0000000000000..7c544d7dd3e2d --- /dev/null +++ b/tests/codegen-llvm/inlining-target-feature-differences.rs @@ -0,0 +1,19 @@ +//@ only-arm +//@ ignore-backends: gcc + +#![feature(arm_target_feature)] +#![crate_type = "lib"] +#![no_std] + +#[inline] +fn callee_neon(a: i32, b: i32) -> i32 { + a + b +} + +#[no_mangle] +#[target_feature(enable = "neon")] +pub fn caller_neon(x: i32, y: i32) -> i32 { + // CHECK-LABEL: define noundef i32 @caller_neon( + // CHECK: [[R:%[0-9A-Za-z_.]+]] = add + callee_neon(x, y) +} diff --git a/tests/codegen-llvm/issues/issue-37945.rs b/tests/codegen-llvm/issues/issue-37945.rs index 23d0eab8ae466..3167a045575a8 100644 --- a/tests/codegen-llvm/issues/issue-37945.rs +++ b/tests/codegen-llvm/issues/issue-37945.rs @@ -1,5 +1,8 @@ //@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled //@ ignore-32bit LLVM has a bug with them +//@ revisions: new old +//@ [old] max-llvm-major-version: 22 +//@ [new] min-llvm-version: 23 // Check that LLVM understands that `Iter` pointer is not null. Issue #37945. @@ -11,8 +14,9 @@ use std::slice::Iter; pub fn is_empty_1(xs: Iter) -> bool { // CHECK-LABEL: @is_empty_1( // CHECK-NEXT: start: - // CHECK-NEXT: [[A:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null - // CHECK-NEXT: tail call void @llvm.assume(i1 [[A]]) + // old-NEXT: [[A:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null + // old-NEXT: tail call void @llvm.assume(i1 [[A]]) + // new-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr {{%xs.0|%xs.1}}) ] // The order between %xs.0 and %xs.1 on the next line doesn't matter // and different LLVM versions produce different order. // CHECK-NEXT: [[B:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}} @@ -24,8 +28,9 @@ pub fn is_empty_1(xs: Iter) -> bool { pub fn is_empty_2(xs: Iter) -> bool { // CHECK-LABEL: @is_empty_2 // CHECK-NEXT: start: - // CHECK-NEXT: [[C:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null - // CHECK-NEXT: tail call void @llvm.assume(i1 [[C]]) + // old-NEXT: [[C:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null + // old-NEXT: tail call void @llvm.assume(i1 [[C]]) + // new-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr {{%xs.0|%xs.1}}) ] // The order between %xs.0 and %xs.1 on the next line doesn't matter // and different LLVM versions produce different order. // CHECK-NEXT: [[D:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}} diff --git a/tests/codegen-llvm/iter-repeat-n-trivial-drop.rs b/tests/codegen-llvm/iter-repeat-n-trivial-drop.rs index a4e5c885a139a..98e906d852f74 100644 --- a/tests/codegen-llvm/iter-repeat-n-trivial-drop.rs +++ b/tests/codegen-llvm/iter-repeat-n-trivial-drop.rs @@ -47,7 +47,7 @@ pub fn iter_repeat_n_next(it: &mut std::iter::RepeatN) -> Option Vec { - // CHECK: %[[ADDR:.+]] = tail call {{(noalias )?}}noundef dereferenceable_or_null(1234) ptr @{{.*}}__rust_alloc(i64 noundef {{(range\(i64 0, -9223372036854775808\) )?}}1234, i64 noundef {{(range\(i64 1, -9223372036854775807\) )?}}1) + // CHECK: %[[ADDR:.+]] = tail call {{(noalias )?}}noundef dereferenceable_or_null(1234) ptr @{{.*}}__rust_alloc(i64 noundef {{(range\(i64 [0-9]+, -9223372036854775808\) )?}}1234, i64 noundef {{(range\(i64 1, -9223372036854775807\) )?}}1) // CHECK: tail call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(1234) %[[ADDR]], i8 42, i64 1234, let n = 1234_usize; diff --git a/tests/ui/README.md b/tests/ui/README.md index 689a61b472691..248f1208d8d9e 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -498,10 +498,6 @@ See: Previously known as "object safety". -## `tests/ui/dyn-drop/`: `dyn Drop` - -**FIXME**: Contains a single test, used only to check the `dyn_drop` lint (which is normally `warn` level). - ## `tests/ui/dyn-keyword/`: `dyn` and Dynamic Dispatch The `dyn` keyword is used to highlight that calls to methods on the associated Trait are dynamically dispatched. To use the trait this way, it must be dyn-compatible - tests about dyn-compatibility belong in `tests/ui/dyn-compatibility/`, while more general tests on dynamic dispatch belong here. @@ -518,10 +514,6 @@ These tests run in specific Rust editions, such as Rust 2015 or Rust 2018, and c Exercises `eii` keyword. -## `tests/ui/empty/`: Various tests related to the concept of "empty" - -**FIXME**: These tests need better homes, this is not very informative. - ## `tests/ui/entry-point/`: `main` function Tests exercising the `main` entry-point. @@ -940,12 +932,6 @@ Something is missing which could be added to fix (e.g. suggestions). **FIXME**: this is way too vague, tests should be rehomed. -## `tests/ui/missing-trait-bounds/` - -Tests for checking missing trait bounds, and their diagnostics. - -**FIXME**: Maybe a subdirectory of `ui/trait-bounds` would be more appropriate. - ## `tests/ui/modules/` Tests on the module system. @@ -1173,12 +1159,6 @@ Broad category of tests exercising recursions (compile test and run time), in fu Also exercises the `#![recursion_limit = ""]` attribute. -## `tests/ui/recursion_limit/`: `#![recursion_limit = ""]` - -Sets a recursion limit on recursive code. - -**FIXME**: Should be merged with `tests/ui/recursion/`. - ## `tests/ui/reflection/` Exercises the `#![feature(type_info)]` feature. @@ -1601,10 +1581,6 @@ Tests on `enum` variants. **FIXME**: Should be rehomed with `tests/ui/enum/`. -## `tests/ui/version/` - -**FIXME**: Contains a single test described as "Check that rustc accepts various version info flags.", should be rehomed. - ## `tests/ui/wasm/` These tests target the `wasm32` architecture specifically. They are usually regression tests for WASM-specific bugs which were observed in the past. diff --git a/tests/ui/attributes/no_link/auxiliary/empty-struct.rs b/tests/ui/attributes/no_link/auxiliary/empty-struct.rs new file mode 100644 index 0000000000000..091db1e76c39e --- /dev/null +++ b/tests/ui/attributes/no_link/auxiliary/empty-struct.rs @@ -0,0 +1 @@ +pub struct XEmpty {} diff --git a/tests/ui/empty/no-link.rs b/tests/ui/attributes/no_link/no-link-struct.rs similarity index 76% rename from tests/ui/empty/no-link.rs rename to tests/ui/attributes/no_link/no-link-struct.rs index 9f78714b7694a..40b0c53185f98 100644 --- a/tests/ui/empty/no-link.rs +++ b/tests/ui/attributes/no_link/no-link-struct.rs @@ -5,5 +5,5 @@ extern crate empty_struct; fn main() { - empty_struct::XEmpty1 {}; + empty_struct::XEmpty {}; } diff --git a/tests/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr b/tests/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr index 41164e99e6d0b..0558def70cfff 100644 --- a/tests/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr +++ b/tests/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr @@ -6,9 +6,9 @@ LL | impl Trait for for<'r> fn(fn(&'r ())) {} LL | impl<'a> Trait for fn(fn(&'a ())) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'r> fn(fn(&'r ()))` | + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details = warning: the behavior may change in a future release = note: for more information, see issue #56105 - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details = note: `#[warn(coherence_leak_check)]` (part of `#[warn(future_incompatible)]`) on by default warning: 1 warning emitted diff --git a/tests/ui/coherence/coherence-fn-implied-bounds.stderr b/tests/ui/coherence/coherence-fn-implied-bounds.stderr index ece3288989d74..aaad1acb22353 100644 --- a/tests/ui/coherence/coherence-fn-implied-bounds.stderr +++ b/tests/ui/coherence/coherence-fn-implied-bounds.stderr @@ -7,9 +7,9 @@ LL | LL | impl Trait for for<'c> fn(&'c &'c u32, &'c &'c u32) -> &'c u32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a &'b u32, &'b &'a u32) -> &'b u32` | + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details = warning: the behavior may change in a future release = note: for more information, see issue #56105 - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details note: the lint level is defined here --> $DIR/coherence-fn-implied-bounds.rs:15:9 | diff --git a/tests/ui/coherence/coherence-fn-inputs.stderr b/tests/ui/coherence/coherence-fn-inputs.stderr index 75df33913a97c..6a0f2ee2b1c2a 100644 --- a/tests/ui/coherence/coherence-fn-inputs.stderr +++ b/tests/ui/coherence/coherence-fn-inputs.stderr @@ -6,9 +6,9 @@ LL | impl Trait for for<'a, 'b> fn(&'a u32, &'b u32) {} LL | impl Trait for for<'c> fn(&'c u32, &'c u32) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u32, &'b u32)` | + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details = warning: the behavior may change in a future release = note: for more information, see issue #56105 - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details = note: `#[warn(coherence_leak_check)]` (part of `#[warn(future_incompatible)]`) on by default warning: 1 warning emitted diff --git a/tests/ui/coherence/coherence-free-vs-bound-region.stderr b/tests/ui/coherence/coherence-free-vs-bound-region.stderr index e45cf5ad3a4c5..9884e1b041ad7 100644 --- a/tests/ui/coherence/coherence-free-vs-bound-region.stderr +++ b/tests/ui/coherence/coherence-free-vs-bound-region.stderr @@ -7,9 +7,9 @@ LL | LL | impl TheTrait for fn(&u8) { | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(&u8)` | + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details = warning: the behavior may change in a future release = note: for more information, see issue #56105 - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details note: the lint level is defined here --> $DIR/coherence-free-vs-bound-region.rs:10:9 | diff --git a/tests/ui/coherence/coherence-subtyping.stderr b/tests/ui/coherence/coherence-subtyping.stderr index f380ea878291a..7817d929da976 100644 --- a/tests/ui/coherence/coherence-subtyping.stderr +++ b/tests/ui/coherence/coherence-subtyping.stderr @@ -7,9 +7,9 @@ LL | LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` | + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details = warning: the behavior may change in a future release = note: for more information, see issue #56105 - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details = note: `#[warn(coherence_leak_check)]` (part of `#[warn(future_incompatible)]`) on by default warning: 1 warning emitted diff --git a/tests/ui/coherence/coherence-wasm-bindgen.stderr b/tests/ui/coherence/coherence-wasm-bindgen.stderr index 939f1fce9a40a..65c64b9beece0 100644 --- a/tests/ui/coherence/coherence-wasm-bindgen.stderr +++ b/tests/ui/coherence/coherence-wasm-bindgen.stderr @@ -13,10 +13,10 @@ LL | | A: RefFromWasmAbi, LL | | R: ReturnWasmAbi, | |_____________________^ conflicting implementation for `&dyn Fn(&_) -> _` | - = warning: the behavior may change in a future release - = note: for more information, see issue #56105 = note: downstream crates may implement trait `FromWasmAbi` for type `&_` = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + = warning: the behavior may change in a future release + = note: for more information, see issue #56105 note: the lint level is defined here --> $DIR/coherence-wasm-bindgen.rs:10:9 | diff --git a/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr b/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr index 8d59cbc3466ba..697a1bc81dbf2 100644 --- a/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr +++ b/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr @@ -6,10 +6,10 @@ LL | impl FnMarker for fn(T) {} LL | impl FnMarker for fn(&T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(&_)` | - = warning: the behavior may change in a future release - = note: for more information, see issue #56105 = note: downstream crates may implement trait `Marker` for type `&_` = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + = warning: the behavior may change in a future release + = note: for more information, see issue #56105 note: the lint level is defined here --> $DIR/negative-coherence-placeholder-region-constraints-on-unification.rs:4:11 | diff --git a/tests/ui/version/version-info-flags.rs b/tests/ui/compile-flags/version-info-flags.rs similarity index 100% rename from tests/ui/version/version-info-flags.rs rename to tests/ui/compile-flags/version-info-flags.rs diff --git a/tests/ui/const-generics/invariant.stderr b/tests/ui/const-generics/invariant.stderr index 095219f6e5fae..465f708d8f132 100644 --- a/tests/ui/const-generics/invariant.stderr +++ b/tests/ui/const-generics/invariant.stderr @@ -7,9 +7,9 @@ LL | impl SadBee for for<'a> fn(&'a ()) { LL | impl SadBee for fn(&'static ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a ())` | + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details = warning: the behavior may change in a future release = note: for more information, see issue #56105 - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details = note: `#[warn(coherence_leak_check)]` (part of `#[warn(future_incompatible)]`) on by default error[E0308]: mismatched types diff --git a/tests/ui/dyn-drop/dyn-drop.rs b/tests/ui/dyn-drop/dyn-drop.rs deleted file mode 100644 index f336949d2cb74..0000000000000 --- a/tests/ui/dyn-drop/dyn-drop.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![deny(dyn_drop)] -fn foo(_: Box) {} //~ ERROR -fn bar(_: &dyn Drop) {} //~ERROR -fn baz(_: *mut dyn Drop) {} //~ ERROR -struct Foo { - _x: Box //~ ERROR -} -trait Bar { - type T: ?Sized; -} -struct Baz {} -impl Bar for Baz { - type T = dyn Drop; //~ ERROR -} -fn main() {} diff --git a/tests/ui/dyn-keyword/dyn-drop.rs b/tests/ui/dyn-keyword/dyn-drop.rs new file mode 100644 index 0000000000000..81753c94a7759 --- /dev/null +++ b/tests/ui/dyn-keyword/dyn-drop.rs @@ -0,0 +1,15 @@ +#![deny(dyn_drop)] +fn foo(_: Box) {} //~ ERROR: types that do not implement `Drop` can still have drop glue, +fn bar(_: &dyn Drop) {} //~ ERROR: types that do not implement `Drop` can still have drop glue, +fn baz(_: *mut dyn Drop) {} //~ ERROR: types that do not implement `Drop` can still have drop glue, +struct Foo { + _x: Box, //~ ERROR: types that do not implement `Drop` can still have drop glue, +} +trait Bar { + type T: ?Sized; +} +struct Baz {} +impl Bar for Baz { + type T = dyn Drop; //~ ERROR: types that do not implement `Drop` can still have drop glue, +} +fn main() {} diff --git a/tests/ui/dyn-drop/dyn-drop.stderr b/tests/ui/dyn-keyword/dyn-drop.stderr similarity index 88% rename from tests/ui/dyn-drop/dyn-drop.stderr rename to tests/ui/dyn-keyword/dyn-drop.stderr index 8210d8a4c48f9..969327ecb84e4 100644 --- a/tests/ui/dyn-drop/dyn-drop.stderr +++ b/tests/ui/dyn-keyword/dyn-drop.stderr @@ -23,16 +23,16 @@ LL | fn baz(_: *mut dyn Drop) {} | ^^^^ error: types that do not implement `Drop` can still have drop glue, consider instead using `std::mem::needs_drop` to detect whether a type is trivially dropped - --> $DIR/dyn-drop.rs:6:15 + --> $DIR/dyn-drop.rs:6:17 | -LL | _x: Box - | ^^^^ +LL | _x: Box, + | ^^^^ error: types that do not implement `Drop` can still have drop glue, consider instead using `std::mem::needs_drop` to detect whether a type is trivially dropped - --> $DIR/dyn-drop.rs:13:16 + --> $DIR/dyn-drop.rs:13:18 | -LL | type T = dyn Drop; - | ^^^^ +LL | type T = dyn Drop; + | ^^^^ error: aborting due to 5 previous errors diff --git a/tests/ui/empty/auxiliary/two_macros.rs b/tests/ui/empty/auxiliary/two_macros.rs deleted file mode 100644 index 2330c75c8e0cb..0000000000000 --- a/tests/ui/empty/auxiliary/two_macros.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[macro_export] -macro_rules! macro_one { () => ("one") } - -#[macro_export] -macro_rules! macro_two { () => ("two") } diff --git a/tests/ui/empty/empty-linkname.rs b/tests/ui/empty/empty-linkname.rs deleted file mode 100644 index 7113d913cd0fa..0000000000000 --- a/tests/ui/empty/empty-linkname.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[link(name = "")] //~ ERROR: link name must not be empty -extern "C" {} - -fn main() {} diff --git a/tests/ui/empty/empty-linkname.stderr b/tests/ui/empty/empty-linkname.stderr deleted file mode 100644 index 9fbcbc3ca9dc8..0000000000000 --- a/tests/ui/empty/empty-linkname.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0454]: link name must not be empty - --> $DIR/empty-linkname.rs:1:15 - | -LL | #[link(name = "")] - | ^^ empty link name - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0454`. diff --git a/tests/ui/empty/issue-37026.rs b/tests/ui/empty/issue-37026.rs deleted file mode 100644 index 2b9dfdcb0f178..0000000000000 --- a/tests/ui/empty/issue-37026.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ aux-build:empty-struct.rs - -extern crate empty_struct; - -fn main() { - let empty_struct::XEmpty2 = (); //~ ERROR mismatched types - let empty_struct::XEmpty6(..) = (); //~ ERROR mismatched types -} diff --git a/tests/ui/empty/empty-attributes.rs b/tests/ui/lint/unused/empty-attributes.rs similarity index 100% rename from tests/ui/empty/empty-attributes.rs rename to tests/ui/lint/unused/empty-attributes.rs diff --git a/tests/ui/empty/empty-attributes.stderr b/tests/ui/lint/unused/empty-attributes.stderr similarity index 100% rename from tests/ui/empty/empty-attributes.stderr rename to tests/ui/lint/unused/empty-attributes.stderr diff --git a/tests/ui/empty/empty-comment.rs b/tests/ui/macros/empty-comment.rs similarity index 100% rename from tests/ui/empty/empty-comment.rs rename to tests/ui/macros/empty-comment.rs diff --git a/tests/ui/empty/empty-comment.stderr b/tests/ui/macros/empty-comment.stderr similarity index 100% rename from tests/ui/empty/empty-comment.stderr rename to tests/ui/macros/empty-comment.stderr diff --git a/tests/ui/empty/empty-macro-use.rs b/tests/ui/macros/macro-use-empty.rs similarity index 100% rename from tests/ui/empty/empty-macro-use.rs rename to tests/ui/macros/macro-use-empty.rs diff --git a/tests/ui/empty/empty-macro-use.stderr b/tests/ui/macros/macro-use-empty.stderr similarity index 88% rename from tests/ui/empty/empty-macro-use.stderr rename to tests/ui/macros/macro-use-empty.stderr index 0b23dd4e1721f..f3997ad3c27f2 100644 --- a/tests/ui/empty/empty-macro-use.stderr +++ b/tests/ui/macros/macro-use-empty.stderr @@ -1,5 +1,5 @@ error: cannot find macro `macro_two` in this scope - --> $DIR/empty-macro-use.rs:8:5 + --> $DIR/macro-use-empty.rs:8:5 | LL | macro_two!(); | ^^^^^^^^^ @@ -10,7 +10,7 @@ LL + use two_macros::macro_two; | warning: unused attribute - --> $DIR/empty-macro-use.rs:3:12 + --> $DIR/macro-use-empty.rs:3:12 | LL | #[macro_use()] | ^^ help: remove these parentheses diff --git a/tests/ui/empty/empty-never-array.rs b/tests/ui/never_type/empty-never-array.rs similarity index 100% rename from tests/ui/empty/empty-never-array.rs rename to tests/ui/never_type/empty-never-array.rs diff --git a/tests/ui/empty/empty-never-array.stderr b/tests/ui/never_type/empty-never-array.stderr similarity index 100% rename from tests/ui/empty/empty-never-array.stderr rename to tests/ui/never_type/empty-never-array.stderr diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index 01fcfdc8be6ee..4963e80ec8ccd 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -4,13 +4,13 @@ error: cannot mutably bind by value within an implicitly-borrowing pattern in Ru LL | let Foo(mut x) = &Foo(0); | ^^^ `mut` binding modifier not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:25:9 | LL | let Foo(mut x) = &Foo(0); | ^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see note: the lint level is defined here --> $DIR/migration_lint.rs:7:9 | @@ -27,13 +27,13 @@ error: cannot mutably bind by value within an implicitly-borrowing pattern in Ru LL | let Foo(mut x) = &mut Foo(0); | ^^^ `mut` binding modifier not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:30:9 | LL | let Foo(mut x) = &mut Foo(0); | ^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut Foo(mut x) = &mut Foo(0); @@ -45,13 +45,13 @@ error: cannot explicitly borrow within an implicitly-borrowing pattern in Rust 2 LL | let Foo(ref x) = &Foo(0); | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:35:9 | LL | let Foo(ref x) = &Foo(0); | ^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: remove the unnecessary binding modifier | LL - let Foo(ref x) = &Foo(0); @@ -64,13 +64,13 @@ error: cannot explicitly borrow within an implicitly-borrowing pattern in Rust 2 LL | let Foo(ref x) = &mut Foo(0); | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:40:9 | LL | let Foo(ref x) = &mut Foo(0); | ^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut Foo(ref x) = &mut Foo(0); @@ -82,13 +82,13 @@ error: cannot explicitly dereference within an implicitly-borrowing pattern in R LL | let Foo(&x) = &Foo(&0); | ^ reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:57:9 | LL | let Foo(&x) = &Foo(&0); | ^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &Foo(&x) = &Foo(&0); @@ -100,13 +100,13 @@ error: cannot explicitly dereference within an implicitly-borrowing pattern in R LL | let Foo(&mut x) = &Foo(&mut 0); | ^^^^ reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:62:9 | LL | let Foo(&mut x) = &Foo(&mut 0); | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &Foo(&mut x) = &Foo(&mut 0); @@ -118,13 +118,13 @@ error: cannot explicitly dereference within an implicitly-borrowing pattern in R LL | let Foo(&x) = &mut Foo(&0); | ^ reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:67:9 | LL | let Foo(&x) = &mut Foo(&0); | ^^^^^^^ this non-reference pattern matches on a reference type `&mut _` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut Foo(&x) = &mut Foo(&0); @@ -136,13 +136,13 @@ error: cannot explicitly dereference within an implicitly-borrowing pattern in R LL | let Foo(&mut x) = &mut Foo(&mut 0); | ^^^^ reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:72:9 | LL | let Foo(&mut x) = &mut Foo(&mut 0); | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut Foo(&mut x) = &mut Foo(&mut 0); @@ -154,13 +154,13 @@ error: cannot explicitly dereference within an implicitly-borrowing pattern in R LL | if let Some(&x) = &&&&&Some(&0u8) { | ^ reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:81:12 | LL | if let Some(&x) = &&&&&Some(&0u8) { | ^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on these references with reference patterns to avoid implicitly borrowing | LL | if let &&&&&Some(&x) = &&&&&Some(&0u8) { @@ -172,13 +172,13 @@ error: cannot explicitly dereference within an implicitly-borrowing pattern in R LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { | ^^^^ reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:87:12 | LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { | ^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on these references with reference patterns to avoid implicitly borrowing | LL | if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) { @@ -190,13 +190,13 @@ error: cannot explicitly dereference within an implicitly-borrowing pattern in R LL | if let Some(&x) = &&&&&mut Some(&0u8) { | ^ reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:93:12 | LL | if let Some(&x) = &&&&&mut Some(&0u8) { | ^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on these references with reference patterns to avoid implicitly borrowing | LL | if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) { @@ -208,13 +208,13 @@ error: cannot explicitly dereference within an implicitly-borrowing pattern in R LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { | ^^^^ reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:99:12 | LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { | ^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on these references with reference patterns and borrow explicitly using a variable binding mode | LL | if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) { @@ -226,13 +226,13 @@ error: cannot mutably bind by value within an implicitly-borrowing pattern in Ru LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; | ^^^ `mut` binding modifier not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:111:9 | LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern and borrow explicitly using variable binding modes | LL | let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 }; @@ -246,13 +246,13 @@ LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; | | | reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:117:9 | LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern and borrow explicitly using a variable binding mode | LL | let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 }; @@ -266,13 +266,13 @@ LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = | | | reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:124:12 | LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on these references with reference patterns and borrow explicitly using a variable binding mode | LL | if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } = @@ -306,8 +306,6 @@ LL | let [&mut [ref a]] = &mut [&mut &[0]]; | | | reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:145:15 | @@ -318,6 +316,8 @@ note: matching on a reference type with a non-reference pattern implicitly borro | LL | let [&mut [ref a]] = &mut [&mut &[0]]; | ^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on these references with reference patterns to avoid implicitly borrowing | LL | let &mut [&mut &[ref a]] = &mut [&mut &[0]]; @@ -329,13 +329,13 @@ error: cannot explicitly dereference within an implicitly-borrowing pattern in R LL | let [&(_)] = &[&0]; | ^ reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:150:9 | LL | let [&(_)] = &[&0]; | ^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &[&(_)] = &[&0]; @@ -349,13 +349,13 @@ LL | let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 }; | | | explicit `ref` binding modifier not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:157:9 | LL | let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: remove the unnecessary binding modifiers | LL - let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 }; @@ -370,13 +370,13 @@ LL | let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 }; | | | explicit `ref` binding modifier not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:164:9 | LL | let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern and borrow explicitly using a variable binding mode | LL | let &mut Struct { ref a, ref mut b, ref mut c } = &mut Struct { a: 0, b: 0, c: 0 }; @@ -390,13 +390,13 @@ LL | let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], | | | reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:172:9 | LL | let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on these references with reference patterns and borrow explicitly using variable binding modes | LL | let &mut &Struct { a: &[ref a], b: &mut [&[ref b]], ref c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 }; @@ -408,13 +408,13 @@ error: cannot explicitly dereference within an implicitly-borrowing pattern in R LL | let Foo(&ref a) = &Foo(&0); | ^ reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:180:9 | LL | let Foo(&ref a) = &Foo(&0); | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &Foo(&ref a) = &Foo(&0); @@ -426,13 +426,13 @@ error: cannot explicitly dereference within an implicitly-borrowing pattern in R LL | let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]); | ^ reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:186:9 | LL | let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]); | ^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on these references with reference patterns and borrow explicitly using variable binding modes | LL | let &(&a, ref b, &[ref c], &mut [&mut (ref d, &[ref e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]); @@ -444,13 +444,13 @@ error: cannot mutably bind by value within an implicitly-borrowing pattern in Ru LL | let (a, [b], [mut c]) = &(0, &mut [0], &[0]); | ^^^ `mut` binding modifier not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:196:9 | LL | let (a, [b], [mut c]) = &(0, &mut [0], &[0]); | ^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on these references with reference patterns and borrow explicitly using variable binding modes | LL | let &(ref a, &mut [ref b], &[mut c]) = &(0, &mut [0], &[0]); @@ -464,13 +464,13 @@ LL | let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0])); | | | reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:204:9 | LL | let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0])); | ^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on these references with reference patterns and borrow explicitly using a variable binding mode | LL | let &(&a, &mut (ref b, &[ref c])) = &(&0, &mut (0, &[0])); @@ -482,13 +482,13 @@ error: cannot mutably bind by value within an implicitly-borrowing pattern in Ru LL | let [mut a @ b] = &[0]; | ^^^ `mut` binding modifier not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:212:9 | LL | let [mut a @ b] = &[0]; | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern and borrow explicitly using a variable binding mode | LL | let &[mut a @ ref b] = &[0]; @@ -500,13 +500,13 @@ error: cannot mutably bind by value within an implicitly-borrowing pattern in Ru LL | let [a @ mut b] = &[0]; | ^^^ `mut` binding modifier not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:219:9 | LL | let [a @ mut b] = &[0]; | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern and borrow explicitly using a variable binding mode | LL | let &[ref a @ mut b] = &[0]; @@ -520,8 +520,6 @@ LL | let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2]; | | | reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:226:31 | @@ -532,6 +530,8 @@ note: matching on a reference type with a non-reference pattern implicitly borro | LL | let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2]; | ^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on these references with reference patterns to avoid implicitly borrowing | LL | let [&Foo(&ref a @ ref b), &Foo(&ref c @ d)] = [&Foo(&0); 2]; @@ -545,8 +545,6 @@ LL | let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2]; | | | reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:235:33 | @@ -557,6 +555,8 @@ note: matching on a reference type with a non-reference pattern implicitly borro | LL | let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2]; | ^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on these references with reference patterns to avoid implicitly borrowing | LL | let [&Foo(&ref a @ [ref b]), &Foo(&ref c @ [d])] = [&Foo(&[0]); 2]; @@ -586,13 +586,13 @@ error: cannot explicitly dereference within an implicitly-borrowing pattern in R LL | let [&migration_lint_macros::bind_ref!(a)] = &[&0]; | ^ reference pattern not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:249:9 | LL | let [&migration_lint_macros::bind_ref!(a)] = &[&0]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &[&migration_lint_macros::bind_ref!(a)] = &[&0]; @@ -606,13 +606,13 @@ LL | let (mut a, ref b) = &(0, 0); | | | `mut` binding modifier not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:255:9 | LL | let (mut a, ref b) = &(0, 0); | ^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &(mut a, ref b) = &(0, 0); @@ -626,13 +626,13 @@ LL | let (mut a, &b) = &(0, &0); | | | `mut` binding modifier not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:261:9 | LL | let (mut a, &b) = &(0, &0); | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &(mut a, &b) = &(0, &0); @@ -647,13 +647,13 @@ LL | let (mut a, ref b, &c) = &(0, 0, &0); | | explicit `ref` binding modifier not allowed when implicitly borrowing | `mut` binding modifier not allowed when implicitly borrowing | - = warning: this changes meaning in Rust 2024 - = note: for more information, see note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:267:9 | LL | let (mut a, ref b, &c) = &(0, 0, &0); | ^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` + = warning: this changes meaning in Rust 2024 + = note: for more information, see help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &(mut a, ref b, &c) = &(0, 0, &0); diff --git a/tests/ui/recursion_limit/issue-40003.rs b/tests/ui/recursion/future-stream-buffer-unordered-40003.rs similarity index 100% rename from tests/ui/recursion_limit/issue-40003.rs rename to tests/ui/recursion/future-stream-buffer-unordered-40003.rs diff --git a/tests/ui/recursion_limit/empty.rs b/tests/ui/recursion/recursion_limit/empty.rs similarity index 100% rename from tests/ui/recursion_limit/empty.rs rename to tests/ui/recursion/recursion_limit/empty.rs diff --git a/tests/ui/recursion_limit/empty.stderr b/tests/ui/recursion/recursion_limit/empty.stderr similarity index 100% rename from tests/ui/recursion_limit/empty.stderr rename to tests/ui/recursion/recursion_limit/empty.stderr diff --git a/tests/ui/recursion_limit/issue-105700.rs b/tests/ui/recursion/recursion_limit/invalid-attribute-105700.rs similarity index 100% rename from tests/ui/recursion_limit/issue-105700.rs rename to tests/ui/recursion/recursion_limit/invalid-attribute-105700.rs diff --git a/tests/ui/recursion_limit/issue-105700.stderr b/tests/ui/recursion/recursion_limit/invalid-attribute-105700.stderr similarity index 66% rename from tests/ui/recursion_limit/issue-105700.stderr rename to tests/ui/recursion/recursion_limit/invalid-attribute-105700.stderr index fd53d248c4e0f..31e230cc64007 100644 --- a/tests/ui/recursion_limit/issue-105700.stderr +++ b/tests/ui/recursion/recursion_limit/invalid-attribute-105700.stderr @@ -1,10 +1,10 @@ error: recursion limit reached while expanding `#[invalid_attribute]` - --> $DIR/issue-105700.rs:6:1 + --> $DIR/invalid-attribute-105700.rs:6:1 | LL | #![invalid_attribute] | ^^^^^^^^^^^^^^^^^^^^^ | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "8"]` attribute to your crate (`issue_105700`) + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "8"]` attribute to your crate (`invalid_attribute_105700`) error: aborting due to 1 previous error diff --git a/tests/ui/recursion_limit/invalid_digit.rs b/tests/ui/recursion/recursion_limit/invalid_digit.rs similarity index 100% rename from tests/ui/recursion_limit/invalid_digit.rs rename to tests/ui/recursion/recursion_limit/invalid_digit.rs diff --git a/tests/ui/recursion_limit/invalid_digit.stderr b/tests/ui/recursion/recursion_limit/invalid_digit.stderr similarity index 100% rename from tests/ui/recursion_limit/invalid_digit.stderr rename to tests/ui/recursion/recursion_limit/invalid_digit.stderr diff --git a/tests/ui/recursion_limit/invalid_digit_type.rs b/tests/ui/recursion/recursion_limit/invalid_digit_type.rs similarity index 100% rename from tests/ui/recursion_limit/invalid_digit_type.rs rename to tests/ui/recursion/recursion_limit/invalid_digit_type.rs diff --git a/tests/ui/recursion_limit/invalid_digit_type.stderr b/tests/ui/recursion/recursion_limit/invalid_digit_type.stderr similarity index 100% rename from tests/ui/recursion_limit/invalid_digit_type.stderr rename to tests/ui/recursion/recursion_limit/invalid_digit_type.stderr diff --git a/tests/ui/recursion_limit/invalid_macro.rs b/tests/ui/recursion/recursion_limit/invalid_macro.rs similarity index 100% rename from tests/ui/recursion_limit/invalid_macro.rs rename to tests/ui/recursion/recursion_limit/invalid_macro.rs diff --git a/tests/ui/recursion_limit/invalid_macro.stderr b/tests/ui/recursion/recursion_limit/invalid_macro.stderr similarity index 100% rename from tests/ui/recursion_limit/invalid_macro.stderr rename to tests/ui/recursion/recursion_limit/invalid_macro.stderr diff --git a/tests/ui/recursion_limit/no-value.rs b/tests/ui/recursion/recursion_limit/no-value.rs similarity index 100% rename from tests/ui/recursion_limit/no-value.rs rename to tests/ui/recursion/recursion_limit/no-value.rs diff --git a/tests/ui/recursion_limit/no-value.stderr b/tests/ui/recursion/recursion_limit/no-value.stderr similarity index 100% rename from tests/ui/recursion_limit/no-value.stderr rename to tests/ui/recursion/recursion_limit/no-value.stderr diff --git a/tests/ui/recursion_limit/overflow.rs b/tests/ui/recursion/recursion_limit/overflow.rs similarity index 100% rename from tests/ui/recursion_limit/overflow.rs rename to tests/ui/recursion/recursion_limit/overflow.rs diff --git a/tests/ui/recursion_limit/overflow.stderr b/tests/ui/recursion/recursion_limit/overflow.stderr similarity index 100% rename from tests/ui/recursion_limit/overflow.stderr rename to tests/ui/recursion/recursion_limit/overflow.stderr diff --git a/tests/ui/recursion_limit/zero-overflow.rs b/tests/ui/recursion/recursion_limit/zero-overflow.rs similarity index 100% rename from tests/ui/recursion_limit/zero-overflow.rs rename to tests/ui/recursion/recursion_limit/zero-overflow.rs diff --git a/tests/ui/recursion_limit/zero-overflow.stderr b/tests/ui/recursion/recursion_limit/zero-overflow.stderr similarity index 100% rename from tests/ui/recursion_limit/zero-overflow.stderr rename to tests/ui/recursion/recursion_limit/zero-overflow.stderr diff --git a/tests/ui/recursion_limit/zero.rs b/tests/ui/recursion/recursion_limit/zero.rs similarity index 100% rename from tests/ui/recursion_limit/zero.rs rename to tests/ui/recursion/recursion_limit/zero.rs diff --git a/tests/ui/recursion_limit/zero.stderr b/tests/ui/recursion/recursion_limit/zero.stderr similarity index 100% rename from tests/ui/recursion_limit/zero.stderr rename to tests/ui/recursion/recursion_limit/zero.stderr diff --git a/tests/ui/empty/auxiliary/empty-struct.rs b/tests/ui/resolve/auxiliary/empty-struct.rs similarity index 100% rename from tests/ui/empty/auxiliary/empty-struct.rs rename to tests/ui/resolve/auxiliary/empty-struct.rs diff --git a/tests/ui/empty/empty-struct-braces-expr.rs b/tests/ui/resolve/empty-struct-braces-expr.rs similarity index 100% rename from tests/ui/empty/empty-struct-braces-expr.rs rename to tests/ui/resolve/empty-struct-braces-expr.rs diff --git a/tests/ui/empty/empty-struct-braces-expr.stderr b/tests/ui/resolve/empty-struct-braces-expr.stderr similarity index 100% rename from tests/ui/empty/empty-struct-braces-expr.stderr rename to tests/ui/resolve/empty-struct-braces-expr.stderr diff --git a/tests/ui/empty/empty-struct-braces-pat-1.rs b/tests/ui/resolve/empty-struct-braces-pat-1.rs similarity index 100% rename from tests/ui/empty/empty-struct-braces-pat-1.rs rename to tests/ui/resolve/empty-struct-braces-pat-1.rs diff --git a/tests/ui/empty/empty-struct-braces-pat-1.stderr b/tests/ui/resolve/empty-struct-braces-pat-1.stderr similarity index 100% rename from tests/ui/empty/empty-struct-braces-pat-1.stderr rename to tests/ui/resolve/empty-struct-braces-pat-1.stderr diff --git a/tests/ui/empty/empty-struct-braces-pat-2.rs b/tests/ui/resolve/empty-struct-braces-pat-2.rs similarity index 100% rename from tests/ui/empty/empty-struct-braces-pat-2.rs rename to tests/ui/resolve/empty-struct-braces-pat-2.rs diff --git a/tests/ui/empty/empty-struct-braces-pat-2.stderr b/tests/ui/resolve/empty-struct-braces-pat-2.stderr similarity index 100% rename from tests/ui/empty/empty-struct-braces-pat-2.stderr rename to tests/ui/resolve/empty-struct-braces-pat-2.stderr diff --git a/tests/ui/empty/empty-struct-braces-pat-3.rs b/tests/ui/resolve/empty-struct-braces-pat-3.rs similarity index 100% rename from tests/ui/empty/empty-struct-braces-pat-3.rs rename to tests/ui/resolve/empty-struct-braces-pat-3.rs diff --git a/tests/ui/empty/empty-struct-braces-pat-3.stderr b/tests/ui/resolve/empty-struct-braces-pat-3.stderr similarity index 100% rename from tests/ui/empty/empty-struct-braces-pat-3.stderr rename to tests/ui/resolve/empty-struct-braces-pat-3.stderr diff --git a/tests/ui/empty/empty-struct-tuple-pat.rs b/tests/ui/resolve/empty-struct-tuple-pat.rs similarity index 100% rename from tests/ui/empty/empty-struct-tuple-pat.rs rename to tests/ui/resolve/empty-struct-tuple-pat.rs diff --git a/tests/ui/empty/empty-struct-tuple-pat.stderr b/tests/ui/resolve/empty-struct-tuple-pat.stderr similarity index 100% rename from tests/ui/empty/empty-struct-tuple-pat.stderr rename to tests/ui/resolve/empty-struct-tuple-pat.stderr diff --git a/tests/ui/empty/empty-struct-unit-expr.rs b/tests/ui/resolve/empty-struct-unit-expr.rs similarity index 100% rename from tests/ui/empty/empty-struct-unit-expr.rs rename to tests/ui/resolve/empty-struct-unit-expr.rs diff --git a/tests/ui/empty/empty-struct-unit-expr.stderr b/tests/ui/resolve/empty-struct-unit-expr.stderr similarity index 100% rename from tests/ui/empty/empty-struct-unit-expr.stderr rename to tests/ui/resolve/empty-struct-unit-expr.stderr diff --git a/tests/ui/empty/empty-struct-unit-pat.rs b/tests/ui/resolve/empty-struct-unit-pat.rs similarity index 100% rename from tests/ui/empty/empty-struct-unit-pat.rs rename to tests/ui/resolve/empty-struct-unit-pat.rs diff --git a/tests/ui/empty/empty-struct-unit-pat.stderr b/tests/ui/resolve/empty-struct-unit-pat.stderr similarity index 100% rename from tests/ui/empty/empty-struct-unit-pat.stderr rename to tests/ui/resolve/empty-struct-unit-pat.stderr diff --git a/tests/ui/missing-trait-bounds/auxiliary/issue-69725.rs b/tests/ui/traits/missing-trait-bounds/auxiliary/struct-69725.rs similarity index 100% rename from tests/ui/missing-trait-bounds/auxiliary/issue-69725.rs rename to tests/ui/traits/missing-trait-bounds/auxiliary/struct-69725.rs diff --git a/tests/ui/missing-trait-bounds/issue-69725.fixed b/tests/ui/traits/missing-trait-bounds/derive-clone-missing-bound-69725.fixed similarity index 64% rename from tests/ui/missing-trait-bounds/issue-69725.fixed rename to tests/ui/traits/missing-trait-bounds/derive-clone-missing-bound-69725.fixed index f23468abcb0a4..aea046b1e771a 100644 --- a/tests/ui/missing-trait-bounds/issue-69725.fixed +++ b/tests/ui/traits/missing-trait-bounds/derive-clone-missing-bound-69725.fixed @@ -1,9 +1,9 @@ //@ run-rustfix -//@ aux-build:issue-69725.rs +//@ aux-build:struct-69725.rs #![allow(dead_code)] -extern crate issue_69725; -use issue_69725::Struct; +extern crate struct_69725; +use struct_69725::Struct; fn crash() where A: Clone { let _ = Struct::::new().clone(); diff --git a/tests/ui/missing-trait-bounds/issue-69725.rs b/tests/ui/traits/missing-trait-bounds/derive-clone-missing-bound-69725.rs similarity index 62% rename from tests/ui/missing-trait-bounds/issue-69725.rs rename to tests/ui/traits/missing-trait-bounds/derive-clone-missing-bound-69725.rs index a51d2540b4ccc..1ea88954e0012 100644 --- a/tests/ui/missing-trait-bounds/issue-69725.rs +++ b/tests/ui/traits/missing-trait-bounds/derive-clone-missing-bound-69725.rs @@ -1,9 +1,9 @@ //@ run-rustfix -//@ aux-build:issue-69725.rs +//@ aux-build:struct-69725.rs #![allow(dead_code)] -extern crate issue_69725; -use issue_69725::Struct; +extern crate struct_69725; +use struct_69725::Struct; fn crash() { let _ = Struct::::new().clone(); diff --git a/tests/ui/missing-trait-bounds/issue-69725.stderr b/tests/ui/traits/missing-trait-bounds/derive-clone-missing-bound-69725.stderr similarity index 54% rename from tests/ui/missing-trait-bounds/issue-69725.stderr rename to tests/ui/traits/missing-trait-bounds/derive-clone-missing-bound-69725.stderr index 20d2213f4f5fe..bed40b83bc37a 100644 --- a/tests/ui/missing-trait-bounds/issue-69725.stderr +++ b/tests/ui/traits/missing-trait-bounds/derive-clone-missing-bound-69725.stderr @@ -1,17 +1,17 @@ -error[E0599]: the method `clone` exists for struct `issue_69725::Struct`, but its trait bounds were not satisfied - --> $DIR/issue-69725.rs:9:32 +error[E0599]: the method `clone` exists for struct `struct_69725::Struct`, but its trait bounds were not satisfied + --> $DIR/derive-clone-missing-bound-69725.rs:9:32 | LL | let _ = Struct::::new().clone(); - | ^^^^^ method cannot be called on `issue_69725::Struct` due to unsatisfied trait bounds + | ^^^^^ method cannot be called on `struct_69725::Struct` due to unsatisfied trait bounds | - ::: $DIR/auxiliary/issue-69725.rs:2:1 + ::: $DIR/auxiliary/struct-69725.rs:2:1 | LL | pub struct Struct(A); - | -------------------- doesn't satisfy `issue_69725::Struct: Clone` + | -------------------- doesn't satisfy `struct_69725::Struct: Clone` | = note: the following trait bounds were not satisfied: `A: Clone` - which is required by `issue_69725::Struct: Clone` + which is required by `struct_69725::Struct: Clone` help: consider restricting the type parameter to satisfy the trait bound | LL | fn crash() where A: Clone { diff --git a/tests/ui/missing-trait-bounds/issue-35677.fixed b/tests/ui/traits/missing-trait-bounds/duplicate-bounds-diagnostic-35677.fixed similarity index 100% rename from tests/ui/missing-trait-bounds/issue-35677.fixed rename to tests/ui/traits/missing-trait-bounds/duplicate-bounds-diagnostic-35677.fixed diff --git a/tests/ui/missing-trait-bounds/issue-35677.rs b/tests/ui/traits/missing-trait-bounds/duplicate-bounds-diagnostic-35677.rs similarity index 100% rename from tests/ui/missing-trait-bounds/issue-35677.rs rename to tests/ui/traits/missing-trait-bounds/duplicate-bounds-diagnostic-35677.rs diff --git a/tests/ui/missing-trait-bounds/issue-35677.stderr b/tests/ui/traits/missing-trait-bounds/duplicate-bounds-diagnostic-35677.stderr similarity index 93% rename from tests/ui/missing-trait-bounds/issue-35677.stderr rename to tests/ui/traits/missing-trait-bounds/duplicate-bounds-diagnostic-35677.stderr index 3bfdd4da6dac8..778a5664c0d79 100644 --- a/tests/ui/missing-trait-bounds/issue-35677.stderr +++ b/tests/ui/traits/missing-trait-bounds/duplicate-bounds-diagnostic-35677.stderr @@ -1,5 +1,5 @@ error[E0599]: the method `is_subset` exists for reference `&HashSet`, but its trait bounds were not satisfied - --> $DIR/issue-35677.rs:7:10 + --> $DIR/duplicate-bounds-diagnostic-35677.rs:7:10 | LL | this.is_subset(other) | ^^^^^^^^^ method cannot be called on `&HashSet` due to unsatisfied trait bounds diff --git a/tests/ui/missing-trait-bounds/missing-trait-bound-for-op.fixed b/tests/ui/traits/missing-trait-bounds/missing-trait-bound-for-op.fixed similarity index 100% rename from tests/ui/missing-trait-bounds/missing-trait-bound-for-op.fixed rename to tests/ui/traits/missing-trait-bounds/missing-trait-bound-for-op.fixed diff --git a/tests/ui/missing-trait-bounds/missing-trait-bound-for-op.rs b/tests/ui/traits/missing-trait-bounds/missing-trait-bound-for-op.rs similarity index 100% rename from tests/ui/missing-trait-bounds/missing-trait-bound-for-op.rs rename to tests/ui/traits/missing-trait-bounds/missing-trait-bound-for-op.rs diff --git a/tests/ui/missing-trait-bounds/missing-trait-bound-for-op.stderr b/tests/ui/traits/missing-trait-bounds/missing-trait-bound-for-op.stderr similarity index 100% rename from tests/ui/missing-trait-bounds/missing-trait-bound-for-op.stderr rename to tests/ui/traits/missing-trait-bounds/missing-trait-bound-for-op.stderr diff --git a/tests/ui/missing-trait-bounds/missing-trait-bounds-for-method-call.rs b/tests/ui/traits/missing-trait-bounds/missing-trait-bounds-for-method-call.rs similarity index 100% rename from tests/ui/missing-trait-bounds/missing-trait-bounds-for-method-call.rs rename to tests/ui/traits/missing-trait-bounds/missing-trait-bounds-for-method-call.rs diff --git a/tests/ui/missing-trait-bounds/missing-trait-bounds-for-method-call.stderr b/tests/ui/traits/missing-trait-bounds/missing-trait-bounds-for-method-call.stderr similarity index 100% rename from tests/ui/missing-trait-bounds/missing-trait-bounds-for-method-call.stderr rename to tests/ui/traits/missing-trait-bounds/missing-trait-bounds-for-method-call.stderr diff --git a/tests/ui/traits/next-solver/find-param-recursion-issue-152716.rs b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.rs new file mode 100644 index 0000000000000..648796483815e --- /dev/null +++ b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.rs @@ -0,0 +1,21 @@ +//@ compile-flags: -Znext-solver + +// Regression test for . +// +// This test checks that we hit the recursion limit for recursively defined projections. +// Normalization of `>::Assoc` could introduce the same projection again. +// Previously, we get into an infinite recursion. + +trait Trait {} +trait Proj<'a> { + type Assoc; +} +fn foo() +where + T: for<'a> Proj<'a, Assoc = for<'b> fn(>::Assoc)>, + (): Trait<>::Assoc> + //~^ ERROR overflow evaluating the requirement `(): Trait<>::Assoc>` [E0275] +{ +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/find-param-recursion-issue-152716.stderr b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.stderr new file mode 100644 index 0000000000000..e2ee83cfadbef --- /dev/null +++ b/tests/ui/traits/next-solver/find-param-recursion-issue-152716.stderr @@ -0,0 +1,11 @@ +error[E0275]: overflow evaluating the requirement `(): Trait<>::Assoc>` + --> $DIR/find-param-recursion-issue-152716.rs:16:9 + | +LL | (): Trait<>::Assoc> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`find_param_recursion_issue_152716`) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/typeck/auxiliary/empty-struct.rs b/tests/ui/typeck/auxiliary/empty-struct.rs new file mode 100644 index 0000000000000..b9ce9de821423 --- /dev/null +++ b/tests/ui/typeck/auxiliary/empty-struct.rs @@ -0,0 +1,2 @@ +pub struct XEmpty1; +pub struct XEmpty2(); diff --git a/tests/ui/typeck/struct-pattern-mismatch-37026.rs b/tests/ui/typeck/struct-pattern-mismatch-37026.rs new file mode 100644 index 0000000000000..f879ef4edeaf1 --- /dev/null +++ b/tests/ui/typeck/struct-pattern-mismatch-37026.rs @@ -0,0 +1,8 @@ +//@ aux-build:empty-struct.rs + +extern crate empty_struct; + +fn main() { + let empty_struct::XEmpty1 = (); //~ ERROR mismatched types + let empty_struct::XEmpty2(..) = (); //~ ERROR mismatched types +} diff --git a/tests/ui/empty/issue-37026.stderr b/tests/ui/typeck/struct-pattern-mismatch-37026.stderr similarity index 64% rename from tests/ui/empty/issue-37026.stderr rename to tests/ui/typeck/struct-pattern-mismatch-37026.stderr index 75c3ab13caccc..b1b40d3482103 100644 --- a/tests/ui/empty/issue-37026.stderr +++ b/tests/ui/typeck/struct-pattern-mismatch-37026.stderr @@ -1,18 +1,18 @@ error[E0308]: mismatched types - --> $DIR/issue-37026.rs:6:9 + --> $DIR/struct-pattern-mismatch-37026.rs:6:9 | -LL | let empty_struct::XEmpty2 = (); +LL | let empty_struct::XEmpty1 = (); | ^^^^^^^^^^^^^^^^^^^^^ -- this expression has type `()` | | - | expected `()`, found `XEmpty2` + | expected `()`, found `XEmpty1` error[E0308]: mismatched types - --> $DIR/issue-37026.rs:7:9 + --> $DIR/struct-pattern-mismatch-37026.rs:7:9 | -LL | let empty_struct::XEmpty6(..) = (); +LL | let empty_struct::XEmpty2(..) = (); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -- this expression has type `()` | | - | expected `()`, found `XEmpty6` + | expected `()`, found `XEmpty2` error: aborting due to 2 previous errors