From 7cb6912f466bf113336c27b6ee4c73165f265105 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 7 Mar 2026 21:15:11 +1100 Subject: [PATCH 01/11] Remove a flaky `got_timeout` assert from two channel tests In CI, the receiver thread can be descheduled for a surprisingly long time, so there's no guarantee that a timeout actually occurs. --- library/std/tests/sync/mpmc.rs | 3 --- library/std/tests/sync/mpsc.rs | 3 --- 2 files changed, 6 deletions(-) diff --git a/library/std/tests/sync/mpmc.rs b/library/std/tests/sync/mpmc.rs index bf80ab96a88bd..db221ff15890e 100644 --- a/library/std/tests/sync/mpmc.rs +++ b/library/std/tests/sync/mpmc.rs @@ -475,7 +475,6 @@ fn stress_recv_timeout_two_threads() { }); let mut recv_count = 0; - let mut got_timeout = false; loop { match rx.recv_timeout(timeout) { Ok(n) => { @@ -483,7 +482,6 @@ fn stress_recv_timeout_two_threads() { recv_count += 1; } Err(RecvTimeoutError::Timeout) => { - got_timeout = true; continue; } Err(RecvTimeoutError::Disconnected) => break, @@ -491,7 +489,6 @@ fn stress_recv_timeout_two_threads() { } assert_eq!(recv_count, stress); - assert!(got_timeout); } #[test] diff --git a/library/std/tests/sync/mpsc.rs b/library/std/tests/sync/mpsc.rs index 9de4a71987b8e..4dc4b955da7c2 100644 --- a/library/std/tests/sync/mpsc.rs +++ b/library/std/tests/sync/mpsc.rs @@ -438,7 +438,6 @@ fn stress_recv_timeout_two_threads() { }); let mut recv_count = 0; - let mut got_timeout = false; loop { match rx.recv_timeout(timeout) { Ok(n) => { @@ -446,7 +445,6 @@ fn stress_recv_timeout_two_threads() { recv_count += 1; } Err(RecvTimeoutError::Timeout) => { - got_timeout = true; continue; } Err(RecvTimeoutError::Disconnected) => break, @@ -454,7 +452,6 @@ fn stress_recv_timeout_two_threads() { } assert_eq!(recv_count, stress); - assert!(got_timeout); } #[test] From 858b82da3b62b44ce0ee9d24fa29dea640f793c8 Mon Sep 17 00:00:00 2001 From: randomicon00 <20146907+randomicon00@users.noreply.github.com> Date: Sun, 8 Mar 2026 22:37:03 -0400 Subject: [PATCH 02/11] Simplify find_attr! for HirId usage Add a HasAttrs<'tcx, Tcx> trait to rustc_hir that allows find_attr! to accept DefId, LocalDefId, OwnerId, and HirId directly, instead of requiring callers to manually fetch the attribute slice first. The trait is defined in rustc_hir with a generic Tcx parameter to avoid a dependency cycle (rustc_hir cannot depend on rustc_middle). The four concrete impls for TyCtxt are in rustc_middle. --- .../src/const_eval/fn_queries.rs | 2 +- compiler/rustc_hir/src/attrs/mod.rs | 26 +++++++++++----- compiler/rustc_hir_typeck/src/loops.rs | 4 +-- .../rustc_interface/src/proc_macro_decls.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 30 +++++++++++++++++++ compiler/rustc_mir_build/src/builder/mod.rs | 2 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 4 +-- compiler/rustc_mir_build/src/thir/cx/mod.rs | 2 +- .../clippy_lints/src/functions/must_use.rs | 6 ++-- .../clippy_lints/src/incompatible_msrv.rs | 2 +- .../clippy_lints/src/manual_non_exhaustive.rs | 4 +-- .../clippy_lints/src/methods/is_empty.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 6 ++-- 13 files changed, 67 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index ad4c9aa5ff9bd..0b5065f12f805 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -37,7 +37,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Constness { } } Node::TraitItem(ti @ TraitItem { kind: TraitItemKind::Fn(..), .. }) => { - if find_attr!(tcx.hir_attrs(ti.hir_id()), RustcNonConstTraitMethod) { + if find_attr!(tcx, ti.hir_id(), RustcNonConstTraitMethod) { Constness::NotConst } else { tcx.trait_def(tcx.local_parent(def_id)).constness diff --git a/compiler/rustc_hir/src/attrs/mod.rs b/compiler/rustc_hir/src/attrs/mod.rs index 09fa144a16041..b3c1deaa48fa8 100644 --- a/compiler/rustc_hir/src/attrs/mod.rs +++ b/compiler/rustc_hir/src/attrs/mod.rs @@ -13,6 +13,15 @@ pub mod diagnostic; mod encode_cross_crate; mod pretty_printing; +/// A trait for types that can provide a list of attributes given a `TyCtxt`. +/// +/// It allows `find_attr!` to accept either a `DefId`, `LocalDefId`, `OwnerId`, or `HirId`. +/// It is defined here with a generic `Tcx` because `rustc_hir` can't depend on `rustc_middle`. +/// The concrete implementations are in `rustc_middle`. +pub trait HasAttrs<'tcx, Tcx> { + fn get_attrs(self, tcx: &Tcx) -> &'tcx [crate::Attribute]; +} + /// Finds attributes in sequences of attributes by pattern matching. /// /// A little like `matches` but for attributes. @@ -34,10 +43,12 @@ mod pretty_printing; /// /// As a convenience, this macro can do that for you! /// -/// Instead of providing an attribute list, provide the `tcx` and a `DefId`. +/// Instead of providing an attribute list, provide the `tcx` and an id +/// (a `DefId`, `LocalDefId`, `OwnerId` or `HirId`). /// /// ```rust,ignore (illustrative) /// find_attr!(tcx, def_id, ) +/// find_attr!(tcx, hir_id, ) /// ``` /// /// Another common case is finding attributes applied to the root of the current crate. @@ -55,13 +66,14 @@ macro_rules! find_attr { $crate::find_attr!($tcx.hir_krate_attrs(), $pattern $(if $guard)? => $e) }; - ($tcx: expr, $def_id: expr, $pattern: pat $(if $guard: expr)?) => { - $crate::find_attr!($tcx, $def_id, $pattern $(if $guard)? => ()).is_some() + ($tcx: expr, $id: expr, $pattern: pat $(if $guard: expr)?) => { + $crate::find_attr!($tcx, $id, $pattern $(if $guard)? => ()).is_some() }; - ($tcx: expr, $def_id: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{ - #[allow(deprecated)] { - $crate::find_attr!($tcx.get_all_attrs($def_id), $pattern $(if $guard)? => $e) - } + ($tcx: expr, $id: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{ + $crate::find_attr!( + $crate::attrs::HasAttrs::get_attrs($id, &$tcx), + $pattern $(if $guard)? => $e + ) }}; diff --git a/compiler/rustc_hir_typeck/src/loops.rs b/compiler/rustc_hir_typeck/src/loops.rs index e77c93641e1a6..21b408064fac5 100644 --- a/compiler/rustc_hir_typeck/src/loops.rs +++ b/compiler/rustc_hir_typeck/src/loops.rs @@ -207,7 +207,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> { }; // A `#[const_continue]` must break to a block in a `#[loop_match]`. - if find_attr!(self.tcx.hir_attrs(e.hir_id), ConstContinue(_)) { + if find_attr!(self.tcx, e.hir_id, ConstContinue(_)) { let Some(label) = break_destination.label else { let span = e.span; self.tcx.dcx().emit_fatal(ConstContinueBadLabel { span }); @@ -420,7 +420,7 @@ impl<'hir> CheckLoopVisitor<'hir> { e: &'hir hir::Expr<'hir>, body: &'hir hir::Block<'hir>, ) -> Option { - if !find_attr!(self.tcx.hir_attrs(e.hir_id), LoopMatch(_)) { + if !find_attr!(self.tcx, e.hir_id, LoopMatch(_)) { return None; } diff --git a/compiler/rustc_interface/src/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs index 63fed51b020a9..eb60c61b0af71 100644 --- a/compiler/rustc_interface/src/proc_macro_decls.rs +++ b/compiler/rustc_interface/src/proc_macro_decls.rs @@ -7,7 +7,7 @@ fn proc_macro_decls_static(tcx: TyCtxt<'_>, (): ()) -> Option { let mut decls = None; for id in tcx.hir_free_items() { - if find_attr!(tcx.hir_attrs(id.hir_id()), RustcProcMacroDecls) { + if find_attr!(tcx, id.hir_id(), RustcProcMacroDecls) { decls = Some(id.owner_id.def_id); } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6abe7d1466990..282d566a4a94a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2199,6 +2199,36 @@ impl<'tcx> TyCtxt<'tcx> { } } +// `HasAttrs` impls: allow `find_attr!(tcx, id, ...)` to work with both DefId-like types and HirId. + +impl<'tcx> hir::attrs::HasAttrs<'tcx, TyCtxt<'tcx>> for DefId { + fn get_attrs(self, tcx: &TyCtxt<'tcx>) -> &'tcx [hir::Attribute] { + if let Some(did) = self.as_local() { + tcx.hir_attrs(tcx.local_def_id_to_hir_id(did)) + } else { + tcx.attrs_for_def(self) + } + } +} + +impl<'tcx> hir::attrs::HasAttrs<'tcx, TyCtxt<'tcx>> for LocalDefId { + fn get_attrs(self, tcx: &TyCtxt<'tcx>) -> &'tcx [hir::Attribute] { + tcx.hir_attrs(tcx.local_def_id_to_hir_id(self)) + } +} + +impl<'tcx> hir::attrs::HasAttrs<'tcx, TyCtxt<'tcx>> for hir::OwnerId { + fn get_attrs(self, tcx: &TyCtxt<'tcx>) -> &'tcx [hir::Attribute] { + hir::attrs::HasAttrs::get_attrs(self.def_id, tcx) + } +} + +impl<'tcx> hir::attrs::HasAttrs<'tcx, TyCtxt<'tcx>> for hir::HirId { + fn get_attrs(self, tcx: &TyCtxt<'tcx>) -> &'tcx [hir::Attribute] { + tcx.hir_attrs(self) + } +} + pub fn provide(providers: &mut Providers) { closure::provide(providers); context::provide(providers); diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index bcac45199437c..01c1e2e79b501 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -491,7 +491,7 @@ fn construct_fn<'tcx>( }; if let Some((dialect, phase)) = - find_attr!(tcx.hir_attrs(fn_id), CustomMir(dialect, phase, _) => (dialect, phase)) + find_attr!(tcx, fn_id, CustomMir(dialect, phase, _) => (dialect, phase)) { return custom::build_custom_mir( tcx, diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index c5eeb8b1aa856..b868fa7984b60 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -873,7 +873,7 @@ impl<'tcx> ThirBuildCx<'tcx> { hir::ExprKind::Ret(v) => ExprKind::Return { value: v.map(|v| self.mirror_expr(v)) }, hir::ExprKind::Become(call) => ExprKind::Become { value: self.mirror_expr(call) }, hir::ExprKind::Break(dest, ref value) => { - if find_attr!(self.tcx.hir_attrs(expr.hir_id), ConstContinue(_)) { + if find_attr!(self.tcx, expr.hir_id, ConstContinue(_)) { match dest.target_id { Ok(target_id) => { let (Some(value), Some(_)) = (value, dest.label) else { @@ -938,7 +938,7 @@ impl<'tcx> ThirBuildCx<'tcx> { match_source, }, hir::ExprKind::Loop(body, ..) => { - if find_attr!(self.tcx.hir_attrs(expr.hir_id), LoopMatch(_)) { + if find_attr!(self.tcx, expr.hir_id, LoopMatch(_)) { let dcx = self.tcx.dcx(); // Accept either `state = expr` or `state = expr;`. diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 60cb509ee9dd2..e3bba5d2f9356 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -104,7 +104,7 @@ impl<'tcx> ThirBuildCx<'tcx> { typing_env: ty::TypingEnv::non_body_analysis(tcx, def), typeck_results, body_owner: def.to_def_id(), - apply_adjustments: !find_attr!(tcx.hir_attrs(hir_id), CustomMir(..) => ()).is_some(), + apply_adjustments: !find_attr!(tcx, hir_id, CustomMir(..)), } } diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs index 04c657104fe1d..7c1b3ef225c6a 100644 --- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs +++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs @@ -24,7 +24,7 @@ use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT}; pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { let attrs = cx.tcx.hir_attrs(item.hir_id()); - let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), MustUse { span, reason } => (span, reason)); + let attr = find_attr!(cx.tcx, item.hir_id(), MustUse { span, reason } => (span, reason)); if let hir::ItemKind::Fn { ref sig, body: ref body_id, @@ -65,7 +65,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); let attrs = cx.tcx.hir_attrs(item.hir_id()); - let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), MustUse { span, reason } => (span, reason)); + let attr = find_attr!(cx.tcx, item.hir_id(), MustUse { span, reason } => (span, reason)); if let Some((attr_span, reason)) = attr { check_needless_must_use( cx, @@ -98,7 +98,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); let attrs = cx.tcx.hir_attrs(item.hir_id()); - let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), MustUse { span, reason } => (span, reason)); + let attr = find_attr!(cx.tcx, item.hir_id(), MustUse { span, reason } => (span, reason)); if let Some((attr_span, reason)) = attr { check_needless_must_use( cx, diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs index ad81810b58cb9..1ae8198a432dd 100644 --- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs +++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs @@ -269,5 +269,5 @@ impl<'tcx> LateLintPass<'tcx> for IncompatibleMsrv { fn is_under_cfg_attribute(cx: &LateContext<'_>, hir_id: HirId) -> bool { cx.tcx .hir_parent_id_iter(hir_id) - .any(|id| find_attr!(cx.tcx.hir_attrs(id), CfgTrace(..) | CfgAttrTrace)) + .any(|id| find_attr!(cx.tcx, id, CfgTrace(..) | CfgAttrTrace)) } diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs index 9ababe87f9dec..703c9137d5437 100644 --- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs +++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs @@ -92,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { .then_some((v.def_id, v.span)) }); if let Ok((id, span)) = iter.exactly_one() - && !find_attr!(cx.tcx.hir_attrs(item.hir_id()), NonExhaustive(..)) + && !find_attr!(cx.tcx, item.hir_id(), NonExhaustive(..)) { self.potential_enums.push((item.owner_id.def_id, id, item.span, span)); } @@ -113,7 +113,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { "this seems like a manual implementation of the non-exhaustive pattern", |diag| { if let Some(non_exhaustive_span) = - find_attr!(cx.tcx.hir_attrs(item.hir_id()), NonExhaustive(span) => *span) + find_attr!(cx.tcx, item.hir_id(), NonExhaustive(span) => *span) { diag.span_note(non_exhaustive_span, "the struct is already non-exhaustive"); } else { diff --git a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs index 4577be34d4a77..cfda39ed08ff1 100644 --- a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs +++ b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs @@ -39,7 +39,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_ fn is_under_cfg(cx: &LateContext<'_>, id: HirId) -> bool { cx.tcx .hir_parent_id_iter(id) - .any(|id| find_attr!(cx.tcx.hir_attrs(id), CfgTrace(..))) + .any(|id| find_attr!(cx.tcx, id, CfgTrace(..))) } /// Similar to [`clippy_utils::expr_or_init`], but does not go up the chain if the initialization diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 1e73e43e0a719..ac66b1e5338d6 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1710,7 +1710,7 @@ pub fn has_attr(attrs: &[hir::Attribute], symbol: Symbol) -> bool { } pub fn has_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { - find_attr!(cx.tcx.hir_attrs(hir_id), Repr { .. }) + find_attr!(cx.tcx, hir_id, Repr { .. }) } pub fn any_parent_has_attr(tcx: TyCtxt<'_>, node: HirId, symbol: Symbol) -> bool { @@ -2362,7 +2362,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl FnOnce(& && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind // We could also check for the type name `test::TestDescAndFn` && let Res::Def(DefKind::Struct, _) = path.res - && find_attr!(tcx.hir_attrs(item.hir_id()), RustcTestMarker(..)) + && find_attr!(tcx, item.hir_id(), RustcTestMarker(..)) { names.push(ident.name); } @@ -2420,7 +2420,7 @@ pub fn is_test_function(tcx: TyCtxt<'_>, fn_def_id: LocalDefId) -> bool { /// This only checks directly applied attributes, to see if a node is inside a `#[cfg(test)]` parent /// use [`is_in_cfg_test`] pub fn is_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool { - if let Some(cfgs) = find_attr!(tcx.hir_attrs(id), CfgTrace(cfgs) => cfgs) + if let Some(cfgs) = find_attr!(tcx, id, CfgTrace(cfgs) => cfgs) && cfgs .iter() .any(|(cfg, _)| matches!(cfg, CfgEntry::NameValue { name: sym::test, .. })) From 4eb9e661ec4bcaae73d084ea24add520c83a7c5e Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sat, 16 Mar 2024 14:53:41 -0400 Subject: [PATCH 03/11] Extend ASCII fast paths of `char` methods beyond ASCII --- library/core/src/char/methods.rs | 33 ++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 87b328c912878..284a3eeb75dfb 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -777,8 +777,9 @@ impl char { #[inline] pub fn is_alphabetic(self) -> bool { match self { - 'a'..='z' | 'A'..='Z' => true, - c => c > '\x7f' && unicode::Alphabetic(c), + 'A'..='Z' | 'a'..='z' => true, + '\0'..='\u{A9}' => false, + _ => unicode::Alphabetic(self), } } @@ -819,7 +820,8 @@ impl char { pub const fn is_lowercase(self) -> bool { match self { 'a'..='z' => true, - c => c > '\x7f' && unicode::Lowercase(c), + '\0'..='\u{A9}' => false, + _ => unicode::Lowercase(self), } } @@ -860,7 +862,8 @@ impl char { pub const fn is_uppercase(self) -> bool { match self { 'A'..='Z' => true, - c => c > '\x7f' && unicode::Uppercase(c), + '\0'..='\u{BF}' => false, + _ => unicode::Uppercase(self), } } @@ -893,7 +896,8 @@ impl char { pub const fn is_whitespace(self) -> bool { match self { ' ' | '\x09'..='\x0d' => true, - c => c > '\x7f' && unicode::White_Space(c), + '\0'..='\u{84}' => false, + _ => unicode::White_Space(self), } } @@ -920,10 +924,10 @@ impl char { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn is_alphanumeric(self) -> bool { - if self.is_ascii() { - self.is_ascii_alphanumeric() - } else { - unicode::Alphabetic(self) || unicode::N(self) + match self { + '0'..='9' | 'A'..='Z' | 'a'..='z' => true, + '\0'..='\u{A9}' => false, + _ => unicode::Alphabetic(self) || unicode::N(self), } } @@ -969,7 +973,7 @@ impl char { #[must_use] #[inline] pub(crate) fn is_grapheme_extended(self) -> bool { - !self.is_ascii() && unicode::Grapheme_Extend(self) + self > '\u{02FF}' && unicode::Grapheme_Extend(self) } /// Returns `true` if this `char` has the `Cased` property. @@ -985,7 +989,11 @@ impl char { #[doc(hidden)] #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")] pub fn is_cased(self) -> bool { - if self.is_ascii() { self.is_ascii_alphabetic() } else { unicode::Cased(self) } + match self { + 'A'..='Z' | 'a'..='z' => true, + '\0'..='\u{A9}' => false, + _ => unicode::Cased(self), + } } /// Returns `true` if this `char` has the `Case_Ignorable` property. @@ -1047,7 +1055,8 @@ impl char { pub fn is_numeric(self) -> bool { match self { '0'..='9' => true, - c => c > '\x7f' && unicode::N(c), + '\0'..='\u{B1}' => false, + _ => unicode::N(self), } } From e844c24122d10c6a4a944ffb1a85c8f36d20a41e Mon Sep 17 00:00:00 2001 From: b-naber Date: Tue, 3 Feb 2026 15:29:55 +0000 Subject: [PATCH 04/11] resolve namespaced crates with open modules --- compiler/rustc_hir/src/def.rs | 19 ++- .../src/hir_ty_lowering/mod.rs | 1 + compiler/rustc_passes/src/dead.rs | 2 +- .../rustc_resolve/src/build_reduced_graph.rs | 1 + compiler/rustc_resolve/src/diagnostics.rs | 8 +- compiler/rustc_resolve/src/ident.rs | 16 +- compiler/rustc_resolve/src/imports.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 144 ++++++++++++------ compiler/rustc_session/src/config/externs.rs | 7 + .../resolve/auxiliary/open-ns-mod-my_api.rs | 9 ++ tests/ui/resolve/auxiliary/open-ns-my_api.rs | 3 + .../resolve/auxiliary/open-ns-my_api_core.rs | 15 ++ .../resolve/auxiliary/open-ns-my_api_utils.rs | 13 ++ tests/ui/resolve/open-ns-1.rs | 19 +++ tests/ui/resolve/open-ns-1.stderr | 22 +++ tests/ui/resolve/open-ns-10.rs | 8 + tests/ui/resolve/open-ns-10.stderr | 2 + tests/ui/resolve/open-ns-11.rs | 12 ++ tests/ui/resolve/open-ns-11.stderr | 9 ++ tests/ui/resolve/open-ns-2.rs | 18 +++ tests/ui/resolve/open-ns-2.stderr | 15 ++ tests/ui/resolve/open-ns-3.rs | 14 ++ tests/ui/resolve/open-ns-3.stderr | 19 +++ tests/ui/resolve/open-ns-4.rs | 12 ++ tests/ui/resolve/open-ns-4.stderr | 9 ++ tests/ui/resolve/open-ns-5.rs | 18 +++ tests/ui/resolve/open-ns-6.rs | 13 ++ tests/ui/resolve/open-ns-7.rs | 14 ++ tests/ui/resolve/open-ns-7.stderr | 16 ++ tests/ui/resolve/open-ns-8.rs | 23 +++ tests/ui/resolve/open-ns-9.rs | 25 +++ tests/ui/resolve/open-ns-9.stderr | 27 ++++ 32 files changed, 481 insertions(+), 54 deletions(-) create mode 100644 tests/ui/resolve/auxiliary/open-ns-mod-my_api.rs create mode 100644 tests/ui/resolve/auxiliary/open-ns-my_api.rs create mode 100644 tests/ui/resolve/auxiliary/open-ns-my_api_core.rs create mode 100644 tests/ui/resolve/auxiliary/open-ns-my_api_utils.rs create mode 100644 tests/ui/resolve/open-ns-1.rs create mode 100644 tests/ui/resolve/open-ns-1.stderr create mode 100644 tests/ui/resolve/open-ns-10.rs create mode 100644 tests/ui/resolve/open-ns-10.stderr create mode 100644 tests/ui/resolve/open-ns-11.rs create mode 100644 tests/ui/resolve/open-ns-11.stderr create mode 100644 tests/ui/resolve/open-ns-2.rs create mode 100644 tests/ui/resolve/open-ns-2.stderr create mode 100644 tests/ui/resolve/open-ns-3.rs create mode 100644 tests/ui/resolve/open-ns-3.stderr create mode 100644 tests/ui/resolve/open-ns-4.rs create mode 100644 tests/ui/resolve/open-ns-4.stderr create mode 100644 tests/ui/resolve/open-ns-5.rs create mode 100644 tests/ui/resolve/open-ns-6.rs create mode 100644 tests/ui/resolve/open-ns-7.rs create mode 100644 tests/ui/resolve/open-ns-7.stderr create mode 100644 tests/ui/resolve/open-ns-8.rs create mode 100644 tests/ui/resolve/open-ns-9.rs create mode 100644 tests/ui/resolve/open-ns-9.stderr diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 3959ee7f94128..76bab70e5c0df 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -590,6 +590,13 @@ pub enum Res { /// **Belongs to the type namespace.** ToolMod, + /// The resolution for an open module in a namespaced crate. E.g. `my_api` + /// in the namespaced crate `my_api::utils` when `my_api` isn't part of the + /// extern prelude. + /// + /// **Belongs to the type namespace.** + OpenMod(Symbol), + // Macro namespace /// An attribute that is *not* implemented via macro. /// E.g., `#[inline]` and `#[rustfmt::skip]`, which are essentially directives, @@ -838,6 +845,7 @@ impl Res { | Res::SelfTyAlias { .. } | Res::SelfCtor(..) | Res::ToolMod + | Res::OpenMod(..) | Res::NonMacroAttr(..) | Res::Err => None, } @@ -869,6 +877,7 @@ impl Res { Res::Local(..) => "local variable", Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => "self type", Res::ToolMod => "tool module", + Res::OpenMod(..) => "namespaced crate", Res::NonMacroAttr(attr_kind) => attr_kind.descr(), Res::Err => "unresolved item", } @@ -895,6 +904,7 @@ impl Res { Res::SelfTyAlias { alias_to, is_trait_impl } } Res::ToolMod => Res::ToolMod, + Res::OpenMod(sym) => Res::OpenMod(sym), Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind), Res::Err => Res::Err, } @@ -911,6 +921,7 @@ impl Res { Res::SelfTyAlias { alias_to, is_trait_impl } } Res::ToolMod => Res::ToolMod, + Res::OpenMod(sym) => Res::OpenMod(sym), Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind), Res::Err => Res::Err, }) @@ -936,9 +947,11 @@ impl Res { pub fn ns(&self) -> Option { match self { Res::Def(kind, ..) => kind.ns(), - Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::ToolMod => { - Some(Namespace::TypeNS) - } + Res::PrimTy(..) + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } + | Res::ToolMod + | Res::OpenMod(..) => Some(Namespace::TypeNS), Res::SelfCtor(..) | Res::Local(..) => Some(Namespace::ValueNS), Res::NonMacroAttr(..) => Some(Namespace::MacroNS), Res::Err => None, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 8b1dad9a65471..c6829a941bbec 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2786,6 +2786,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { | Res::SelfCtor(_) | Res::Local(_) | Res::ToolMod + | Res::OpenMod(..) | Res::NonMacroAttr(_) | Res::Err) => Const::new_error_with_message( tcx, diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 15c91deef247d..30634c800e819 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -157,7 +157,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { Res::Def(_, def_id) => self.check_def_id(def_id), Res::SelfTyParam { trait_: t } => self.check_def_id(t), Res::SelfTyAlias { alias_to: i, .. } => self.check_def_id(i), - Res::ToolMod | Res::NonMacroAttr(..) | Res::Err => {} + Res::ToolMod | Res::NonMacroAttr(..) | Res::OpenMod(..) | Res::Err => {} } } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index a280acc0d51df..af9680ac8888d 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -357,6 +357,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::SelfCtor(..) + | Res::OpenMod(..) | Res::Err => bug!("unexpected resolution: {:?}", res), } } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index c776020c21274..fd5bf2da5fc6f 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1,3 +1,4 @@ +// ignore-tidy-filelength use std::ops::ControlFlow; use itertools::Itertools as _; @@ -1735,8 +1736,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Res::Def(DefKind::Macro(kinds), _) => { format!("{} {}", kinds.article(), kinds.descr()) } - Res::ToolMod => { - // Don't confuse the user with tool modules. + Res::ToolMod | Res::OpenMod(..) => { + // Don't confuse the user with tool modules or open modules. continue; } Res::Def(DefKind::Trait, _) if macro_kind == MacroKind::Derive => { @@ -1973,7 +1974,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let (built_in, from) = match scope { Scope::StdLibPrelude | Scope::MacroUsePrelude => ("", " from prelude"), Scope::ExternPreludeFlags - if self.tcx.sess.opts.externs.get(ident.as_str()).is_some() => + if self.tcx.sess.opts.externs.get(ident.as_str()).is_some() + || matches!(res, Res::OpenMod(..)) => { ("", " passed with `--extern`") } diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 7cfd5b5f861a4..cd3f63304f02d 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -26,7 +26,7 @@ use crate::{ AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingKey, CmResolver, Decl, DeclKind, Determinacy, Finalize, IdentKey, ImportKind, LateDecl, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet, - Segment, Stage, Used, errors, + Segment, Stage, Symbol, Used, errors, }; #[derive(Copy, Clone)] @@ -386,7 +386,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } /// Resolve an identifier in the specified set of scopes. - #[instrument(level = "debug", skip(self))] pub(crate) fn resolve_ident_in_scope_set<'r>( self: CmResolver<'r, 'ra, 'tcx>, orig_ident: Ident, @@ -976,6 +975,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ignore_import, ) } + ModuleOrUniformRoot::OpenModule(sym) => { + let open_ns_name = format!("{}::{}", sym.as_str(), ident.name); + let ns_ident = IdentKey::with_root_ctxt(Symbol::intern(&open_ns_name)); + match self.extern_prelude_get_flag(ns_ident, ident.span, finalize.is_some()) { + Some(decl) => Ok(decl), + None => Err(Determinacy::Determined), + } + } ModuleOrUniformRoot::ModuleAndExternPrelude(module) => self.resolve_ident_in_scope_set( ident, ScopeSet::ModuleAndExternPrelude(ns, module), @@ -1962,7 +1969,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res); - if let Some(def_id) = binding.res().module_like_def_id() { + if let Res::OpenMod(sym) = binding.res() { + module = Some(ModuleOrUniformRoot::OpenModule(sym)); + record_segment_res(self.reborrow(), finalize, res, id); + } else if let Some(def_id) = binding.res().module_like_def_id() { if self.mods_with_parse_errors.contains(&def_id) { module_had_parse_errors = true; } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 7696b4b220d6c..8f534de0f76dd 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -41,7 +41,7 @@ type Res = def::Res; /// A potential import declaration in the process of being planted into a module. /// Also used for lazily planting names from `--extern` flags to extern prelude. -#[derive(Clone, Copy, Default, PartialEq)] +#[derive(Clone, Copy, Default, PartialEq, Debug)] pub(crate) enum PendingDecl<'ra> { Ready(Option>), #[default] diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 6b3b5e2ec45f0..9aa96ce27e084 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -64,6 +64,7 @@ use rustc_hir::definitions::DisambiguatorState; use rustc_hir::{PrimTy, TraitCandidate, find_attr}; use rustc_index::bit_set::DenseBitSet; use rustc_metadata::creader::CStore; +use rustc_middle::bug; use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport}; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::query::Providers; @@ -448,6 +449,11 @@ enum ModuleOrUniformRoot<'ra> { /// Used only for resolving single-segment imports. The reason it exists is that import paths /// are always split into two parts, the first of which should be some kind of module. CurrentScope, + + /// Virtual module for the resolution of base names of namespaced crates, + /// where the base name doesn't correspond to a module in the extern prelude. + /// E.g. `my_api::utils` is in the prelude, but `my_api` is not. + OpenModule(Symbol), } #[derive(Debug)] @@ -1108,13 +1114,20 @@ impl<'ra> DeclData<'ra> { } } +#[derive(Debug)] struct ExternPreludeEntry<'ra> { /// Name declaration from an `extern crate` item. /// The boolean flag is true is `item_decl` is non-redundant, happens either when /// `flag_decl` is `None`, or when `extern crate` introducing `item_decl` used renaming. item_decl: Option<(Decl<'ra>, Span, /* introduced by item */ bool)>, /// Name declaration from an `--extern` flag, lazily populated on first use. - flag_decl: Option, /* finalized */ bool)>>, + flag_decl: Option< + CacheCell<( + PendingDecl<'ra>, + /* finalized */ bool, + /* open flag (namespaced crate) */ bool, + )>, + >, } impl ExternPreludeEntry<'_> { @@ -1125,7 +1138,14 @@ impl ExternPreludeEntry<'_> { fn flag() -> Self { ExternPreludeEntry { item_decl: None, - flag_decl: Some(CacheCell::new((PendingDecl::Pending, false))), + flag_decl: Some(CacheCell::new((PendingDecl::Pending, false, false))), + } + } + + fn open_flag() -> Self { + ExternPreludeEntry { + item_decl: None, + flag_decl: Some(CacheCell::new((PendingDecl::Pending, false, true))), } } @@ -1637,35 +1657,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut invocation_parents = FxHashMap::default(); invocation_parents.insert(LocalExpnId::ROOT, InvocationParent::ROOT); - let mut extern_prelude: FxIndexMap<_, _> = tcx - .sess - .opts - .externs - .iter() - .filter_map(|(name, entry)| { - // Make sure `self`, `super`, `_` etc do not get into extern prelude. - // FIXME: reject `--extern self` and similar in option parsing instead. - if entry.add_prelude - && let name = Symbol::intern(name) - && name.can_be_raw() - { - let ident = IdentKey::with_root_ctxt(name); - Some((ident, ExternPreludeEntry::flag())) - } else { - None - } - }) - .collect(); - - if !attr::contains_name(attrs, sym::no_core) { - let ident = IdentKey::with_root_ctxt(sym::core); - extern_prelude.insert(ident, ExternPreludeEntry::flag()); - if !attr::contains_name(attrs, sym::no_std) { - let ident = IdentKey::with_root_ctxt(sym::std); - extern_prelude.insert(ident, ExternPreludeEntry::flag()); - } - } - + let extern_prelude = build_extern_prelude(tcx, attrs); let registered_tools = tcx.registered_tools(()); let edition = tcx.sess.edition(); @@ -2320,10 +2312,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) -> Option> { let entry = self.extern_prelude.get(&ident); entry.and_then(|entry| entry.flag_decl.as_ref()).and_then(|flag_decl| { - let (pending_decl, finalized) = flag_decl.get(); + let (pending_decl, finalized, is_open) = flag_decl.get(); let decl = match pending_decl { PendingDecl::Ready(decl) => { - if finalize && !finalized { + if finalize && !finalized && !is_open { self.cstore_mut().process_path_extern( self.tcx, ident.name, @@ -2334,18 +2326,28 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } PendingDecl::Pending => { debug_assert!(!finalized); - let crate_id = if finalize { - self.cstore_mut().process_path_extern(self.tcx, ident.name, orig_ident_span) + if is_open { + let res = Res::OpenMod(ident.name); + Some(self.arenas.new_pub_def_decl(res, DUMMY_SP, LocalExpnId::ROOT)) } else { - self.cstore_mut().maybe_process_path_extern(self.tcx, ident.name) - }; - crate_id.map(|crate_id| { - let res = Res::Def(DefKind::Mod, crate_id.as_def_id()); - self.arenas.new_pub_def_decl(res, DUMMY_SP, LocalExpnId::ROOT) - }) + let crate_id = if finalize { + self.cstore_mut().process_path_extern( + self.tcx, + ident.name, + orig_ident_span, + ) + } else { + self.cstore_mut().maybe_process_path_extern(self.tcx, ident.name) + }; + crate_id.map(|crate_id| { + let def_id = crate_id.as_def_id(); + let res = Res::Def(DefKind::Mod, def_id); + self.arenas.new_pub_def_decl(res, DUMMY_SP, LocalExpnId::ROOT) + }) + } } }; - flag_decl.set((PendingDecl::Ready(decl), finalize || finalized)); + flag_decl.set((PendingDecl::Ready(decl), finalize || finalized, is_open)); decl.or_else(|| finalize.then_some(self.dummy_decl)) }) } @@ -2387,7 +2389,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { PathResult::Module(ModuleOrUniformRoot::ExternPrelude) | PathResult::Failed { .. } => { None } - PathResult::Module(..) | PathResult::Indeterminate => unreachable!(), + path_result @ (PathResult::Module(..) | PathResult::Indeterminate) => { + bug!("got invalid path_result: {path_result:?}") + } } } @@ -2505,6 +2509,60 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } +fn build_extern_prelude<'tcx, 'ra>( + tcx: TyCtxt<'tcx>, + attrs: &[ast::Attribute], +) -> FxIndexMap> { + let mut extern_prelude: FxIndexMap> = tcx + .sess + .opts + .externs + .iter() + .filter_map(|(name, entry)| { + // Make sure `self`, `super`, `_` etc do not get into extern prelude. + // FIXME: reject `--extern self` and similar in option parsing instead. + if entry.add_prelude + && let sym = Symbol::intern(name) + && sym.can_be_raw() + { + Some((IdentKey::with_root_ctxt(sym), ExternPreludeEntry::flag())) + } else { + None + } + }) + .collect(); + + // Add open base entries for namespaced crates whose base segment + // is missing from the prelude (e.g. `foo::bar` without `foo`). + // These are necessary in order to resolve the open modules, whereas + // the namespaced names are necessary in `extern_prelude` for actually + // resolving the namespaced crates. + let missing_open_bases: Vec = extern_prelude + .keys() + .filter_map(|ident| { + let (base, _) = ident.name.as_str().split_once("::")?; + let base_sym = Symbol::intern(base); + base_sym.can_be_raw().then(|| IdentKey::with_root_ctxt(base_sym)) + }) + .filter(|base_ident| !extern_prelude.contains_key(base_ident)) + .collect(); + + extern_prelude.extend( + missing_open_bases.into_iter().map(|ident| (ident, ExternPreludeEntry::open_flag())), + ); + + // Inject `core` / `std` unless suppressed by attributes. + if !attr::contains_name(attrs, sym::no_core) { + extern_prelude.insert(IdentKey::with_root_ctxt(sym::core), ExternPreludeEntry::flag()); + + if !attr::contains_name(attrs, sym::no_std) { + extern_prelude.insert(IdentKey::with_root_ctxt(sym::std), ExternPreludeEntry::flag()); + } + } + + extern_prelude +} + fn names_to_string(names: impl Iterator) -> String { let mut result = String::new(); for (i, name) in names.enumerate().filter(|(_, name)| *name != kw::PathRoot) { diff --git a/compiler/rustc_session/src/config/externs.rs b/compiler/rustc_session/src/config/externs.rs index d668d8b4203db..ff76eaaeaf4fc 100644 --- a/compiler/rustc_session/src/config/externs.rs +++ b/compiler/rustc_session/src/config/externs.rs @@ -43,6 +43,13 @@ pub(crate) fn split_extern_opt<'a>( } }; + // Reject paths with more than two segments. + if unstable_opts.namespaced_crates && crate_name.split("::").count() > 2 { + return Err(early_dcx.early_struct_fatal(format!( + "crate name `{crate_name}` passed to `--extern` can have at most two segments." + ))); + } + if !valid_crate_name(&crate_name, unstable_opts) { let mut error = early_dcx.early_struct_fatal(format!( "crate name `{crate_name}` passed to `--extern` is not a valid ASCII identifier" diff --git a/tests/ui/resolve/auxiliary/open-ns-mod-my_api.rs b/tests/ui/resolve/auxiliary/open-ns-mod-my_api.rs new file mode 100644 index 0000000000000..dc8b5720c0c10 --- /dev/null +++ b/tests/ui/resolve/auxiliary/open-ns-mod-my_api.rs @@ -0,0 +1,9 @@ +pub mod utils { + pub fn root_helper() { + println!("root_helper"); + } +} + +pub fn root_function() -> String { + "my_api root!".to_string() +} diff --git a/tests/ui/resolve/auxiliary/open-ns-my_api.rs b/tests/ui/resolve/auxiliary/open-ns-my_api.rs new file mode 100644 index 0000000000000..be4bf31f0fbcd --- /dev/null +++ b/tests/ui/resolve/auxiliary/open-ns-my_api.rs @@ -0,0 +1,3 @@ +pub fn root_function() -> String { + "my_api root!".to_string() +} diff --git a/tests/ui/resolve/auxiliary/open-ns-my_api_core.rs b/tests/ui/resolve/auxiliary/open-ns-my_api_core.rs new file mode 100644 index 0000000000000..41418f1516f60 --- /dev/null +++ b/tests/ui/resolve/auxiliary/open-ns-my_api_core.rs @@ -0,0 +1,15 @@ +// #![crate_name = "my_api::core"] + +pub mod util { + pub fn core_mod_fn() -> String { + format!("core_fn from my_api::core::util",) + } +} + +pub fn core_fn() -> String { + format!("core_fn from my_api::core!",) +} + +pub fn core_fn2() -> String { + format!("core_fn2 from my_api::core!",) +} diff --git a/tests/ui/resolve/auxiliary/open-ns-my_api_utils.rs b/tests/ui/resolve/auxiliary/open-ns-my_api_utils.rs new file mode 100644 index 0000000000000..d2af20728bd5e --- /dev/null +++ b/tests/ui/resolve/auxiliary/open-ns-my_api_utils.rs @@ -0,0 +1,13 @@ +pub mod util { + pub fn util_mod_helper() -> String { + format!("Helper from my_api::utils::util",) + } +} + +pub fn utils_helper() -> String { + format!("Helper from my_api::utils!",) +} + +pub fn get_u32() -> u32 { + 1 +} diff --git a/tests/ui/resolve/open-ns-1.rs b/tests/ui/resolve/open-ns-1.rs new file mode 100644 index 0000000000000..e77ddbe58122d --- /dev/null +++ b/tests/ui/resolve/open-ns-1.rs @@ -0,0 +1,19 @@ +//@ aux-crate:my_api=open-ns-my_api.rs +//@ aux-crate:my_api::utils=open-ns-my_api_utils.rs +//@ aux-crate:my_api::core=open-ns-my_api_core.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 + +use my_api::root_function; +use my_api::utils::util; +//~^ ERROR unresolved import `my_api::utils` + +fn main() { + let _ = root_function(); + let _ = my_api::root_function(); + let _ = my_api::utils::utils_helper(); + //~^ ERROR cannot find `utils` in `my_api` [E0433] + let _ = util::util_mod_helper(); + let _ = my_api::core::core_fn(); + //~^ ERROR cannot find `core` in `my_api` [E0433] +} diff --git a/tests/ui/resolve/open-ns-1.stderr b/tests/ui/resolve/open-ns-1.stderr new file mode 100644 index 0000000000000..65b9c6a355ce0 --- /dev/null +++ b/tests/ui/resolve/open-ns-1.stderr @@ -0,0 +1,22 @@ +error[E0432]: unresolved import `my_api::utils` + --> $DIR/open-ns-1.rs:8:13 + | +LL | use my_api::utils::util; + | ^^^^^ could not find `utils` in `my_api` + +error[E0433]: cannot find `utils` in `my_api` + --> $DIR/open-ns-1.rs:14:21 + | +LL | let _ = my_api::utils::utils_helper(); + | ^^^^^ could not find `utils` in `my_api` + +error[E0433]: cannot find `core` in `my_api` + --> $DIR/open-ns-1.rs:17:21 + | +LL | let _ = my_api::core::core_fn(); + | ^^^^ could not find `core` in `my_api` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0432, E0433. +For more information about an error, try `rustc --explain E0432`. diff --git a/tests/ui/resolve/open-ns-10.rs b/tests/ui/resolve/open-ns-10.rs new file mode 100644 index 0000000000000..b05a0ab270df0 --- /dev/null +++ b/tests/ui/resolve/open-ns-10.rs @@ -0,0 +1,8 @@ +// Tests that namespaced crate names are limited to two segments + +//@ aux-crate: nscrate::three::segments=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 +//~? ERROR crate name `nscrate::three::segments` passed to `--extern` can have at most two segments. + +fn main() {} diff --git a/tests/ui/resolve/open-ns-10.stderr b/tests/ui/resolve/open-ns-10.stderr new file mode 100644 index 0000000000000..fdef748c6fa7d --- /dev/null +++ b/tests/ui/resolve/open-ns-10.stderr @@ -0,0 +1,2 @@ +error: crate name `nscrate::three::segments` passed to `--extern` can have at most two segments. + diff --git a/tests/ui/resolve/open-ns-11.rs b/tests/ui/resolve/open-ns-11.rs new file mode 100644 index 0000000000000..90e85a9ffc043 --- /dev/null +++ b/tests/ui/resolve/open-ns-11.rs @@ -0,0 +1,12 @@ +// Tests that std has higher precedence than an open module with the same name. + +//@ aux-crate: std::utils=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 + +use std::utils::get_u32; +//~^ ERROR unresolved import `std::utils` + +fn main() { + let _ = get_u32(); +} diff --git a/tests/ui/resolve/open-ns-11.stderr b/tests/ui/resolve/open-ns-11.stderr new file mode 100644 index 0000000000000..cb073bc985a9e --- /dev/null +++ b/tests/ui/resolve/open-ns-11.stderr @@ -0,0 +1,9 @@ +error[E0432]: unresolved import `std::utils` + --> $DIR/open-ns-11.rs:7:10 + | +LL | use std::utils::get_u32; + | ^^^^^ could not find `utils` in `std` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0432`. diff --git a/tests/ui/resolve/open-ns-2.rs b/tests/ui/resolve/open-ns-2.rs new file mode 100644 index 0000000000000..6165a4102be07 --- /dev/null +++ b/tests/ui/resolve/open-ns-2.rs @@ -0,0 +1,18 @@ +//@ aux-crate: my_api=open-ns-my_api.rs +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ aux-crate: my_api::core=open-ns-my_api_core.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 + +use my_api::core::{core_fn, core_fn2}; +//~^ ERROR unresolved import `my_api::core` [E0432] +use my_api::utils::*; +//~^ ERROR unresolved import `my_api::utils` [E0432] +use my_api::*; + +fn main() { + let _ = root_function(); + let _ = utils_helper(); + let _ = core_fn(); + let _ = core_fn2(); +} diff --git a/tests/ui/resolve/open-ns-2.stderr b/tests/ui/resolve/open-ns-2.stderr new file mode 100644 index 0000000000000..0e221234c5179 --- /dev/null +++ b/tests/ui/resolve/open-ns-2.stderr @@ -0,0 +1,15 @@ +error[E0432]: unresolved import `my_api::core` + --> $DIR/open-ns-2.rs:7:13 + | +LL | use my_api::core::{core_fn, core_fn2}; + | ^^^^ could not find `core` in `my_api` + +error[E0432]: unresolved import `my_api::utils` + --> $DIR/open-ns-2.rs:9:13 + | +LL | use my_api::utils::*; + | ^^^^^ could not find `utils` in `my_api` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0432`. diff --git a/tests/ui/resolve/open-ns-3.rs b/tests/ui/resolve/open-ns-3.rs new file mode 100644 index 0000000000000..9c78999fe3687 --- /dev/null +++ b/tests/ui/resolve/open-ns-3.rs @@ -0,0 +1,14 @@ +// This test should fail with `utils_helper` being unresolvable in `my_api::utils`. +// If a crate contains a module that overlaps with a namespaced crate name, then +// the namespaced crate will not be used in name resolution. + +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ aux-crate: my_api=open-ns-mod-my_api.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 + +fn main() { + let _ = my_api::utils::root_helper(); + let _ = my_api::utils::utils_helper(); + //~^ ERROR cannot find function `utils_helper` in module `my_api::utils` [E0425] +} diff --git a/tests/ui/resolve/open-ns-3.stderr b/tests/ui/resolve/open-ns-3.stderr new file mode 100644 index 0000000000000..8ae261af01429 --- /dev/null +++ b/tests/ui/resolve/open-ns-3.stderr @@ -0,0 +1,19 @@ +error[E0425]: cannot find function `utils_helper` in module `my_api::utils` + --> $DIR/open-ns-3.rs:12:28 + | +LL | let _ = my_api::utils::utils_helper(); + | ^^^^^^^^^^^^ not found in `my_api::utils` + | +help: consider importing this function + | +LL + use my_api::utils::utils_helper; + | +help: if you import `utils_helper`, refer to it directly + | +LL - let _ = my_api::utils::utils_helper(); +LL + let _ = utils_helper(); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/resolve/open-ns-4.rs b/tests/ui/resolve/open-ns-4.rs new file mode 100644 index 0000000000000..4db3ad4c80a1d --- /dev/null +++ b/tests/ui/resolve/open-ns-4.rs @@ -0,0 +1,12 @@ +// This tests that namespaced crates are shadowed. + +//@ aux-crate: my_api=open-ns-my_api.rs +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 + +fn main() { + let _ = my_api::root_function(); + let _ = my_api::utils::utils_helper(); + //~^ ERROR cannot find `utils` in `my_api` [E0433] +} diff --git a/tests/ui/resolve/open-ns-4.stderr b/tests/ui/resolve/open-ns-4.stderr new file mode 100644 index 0000000000000..2e6872c57986f --- /dev/null +++ b/tests/ui/resolve/open-ns-4.stderr @@ -0,0 +1,9 @@ +error[E0433]: cannot find `utils` in `my_api` + --> $DIR/open-ns-4.rs:10:21 + | +LL | let _ = my_api::utils::utils_helper(); + | ^^^^^ could not find `utils` in `my_api` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/resolve/open-ns-5.rs b/tests/ui/resolve/open-ns-5.rs new file mode 100644 index 0000000000000..8776da3106cf8 --- /dev/null +++ b/tests/ui/resolve/open-ns-5.rs @@ -0,0 +1,18 @@ +// Tests that namespaced crate names work inside macros. + +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 +//@ check-pass + +macro_rules! import_and_call { + ($import_path:path, $fn_name:ident) => {{ + use $import_path; + $fn_name(); + }}; +} + +fn main() { + import_and_call!(my_api::utils::utils_helper, utils_helper); + let _x = 4 + 5; +} diff --git a/tests/ui/resolve/open-ns-6.rs b/tests/ui/resolve/open-ns-6.rs new file mode 100644 index 0000000000000..856858aac43a5 --- /dev/null +++ b/tests/ui/resolve/open-ns-6.rs @@ -0,0 +1,13 @@ +// Tests that open modules are resolvable. + +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 +//@ check-pass + +use my_api; +use my_api::utils::utils_helper; + +fn main() { + let _ = utils_helper(); +} diff --git a/tests/ui/resolve/open-ns-7.rs b/tests/ui/resolve/open-ns-7.rs new file mode 100644 index 0000000000000..cf16c594fa40b --- /dev/null +++ b/tests/ui/resolve/open-ns-7.rs @@ -0,0 +1,14 @@ +// Tests that namespaced crates cannot be resolved if shadowed. + +//@ aux-crate: my_api=open-ns-my_api.rs +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 + +use my_api::utils::utils_helper; +//~^ ERROR unresolved import `my_api::utils` [E0432] + +fn main() { + let _ = my_api::utils::utils_helper(); + //~^ ERROR cannot find `utils` in `my_api` [E0433] +} diff --git a/tests/ui/resolve/open-ns-7.stderr b/tests/ui/resolve/open-ns-7.stderr new file mode 100644 index 0000000000000..b008547539831 --- /dev/null +++ b/tests/ui/resolve/open-ns-7.stderr @@ -0,0 +1,16 @@ +error[E0432]: unresolved import `my_api::utils` + --> $DIR/open-ns-7.rs:8:13 + | +LL | use my_api::utils::utils_helper; + | ^^^^^ could not find `utils` in `my_api` + +error[E0433]: cannot find `utils` in `my_api` + --> $DIR/open-ns-7.rs:12:21 + | +LL | let _ = my_api::utils::utils_helper(); + | ^^^^^ could not find `utils` in `my_api` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0432, E0433. +For more information about an error, try `rustc --explain E0432`. diff --git a/tests/ui/resolve/open-ns-8.rs b/tests/ui/resolve/open-ns-8.rs new file mode 100644 index 0000000000000..46aafb66e63a6 --- /dev/null +++ b/tests/ui/resolve/open-ns-8.rs @@ -0,0 +1,23 @@ +// Tests that a macro-generated item has higher precendence than a namespaced crate +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 +//@ check-pass + +macro_rules! define { + () => { + pub mod my_api { + pub mod utils { + pub fn get_u32() -> u32 { + 2 + } + } + } + }; +} + +fn main() { + define!(); + let res = my_api::utils::get_u32(); + assert_eq!(res, 2); +} diff --git a/tests/ui/resolve/open-ns-9.rs b/tests/ui/resolve/open-ns-9.rs new file mode 100644 index 0000000000000..7ded0b383d8d4 --- /dev/null +++ b/tests/ui/resolve/open-ns-9.rs @@ -0,0 +1,25 @@ +//@ aux-crate: my_api::utils=open-ns-my_api_utils.rs +//@ compile-flags: -Z namespaced-crates +//@ edition: 2024 + +use my_api::utils::get_u32; +//~^ ERROR `my_api` is ambiguous [E0659] + +macro_rules! define { + () => { + pub mod my_api { + pub mod utils { + pub fn get_u32() -> u32 { + 2 + } + } + } + }; +} + +define!(); + +fn main() { + let val = get_u32(); + assert_eq!(val, 2); +} diff --git a/tests/ui/resolve/open-ns-9.stderr b/tests/ui/resolve/open-ns-9.stderr new file mode 100644 index 0000000000000..675f487823e55 --- /dev/null +++ b/tests/ui/resolve/open-ns-9.stderr @@ -0,0 +1,27 @@ +error[E0659]: `my_api` is ambiguous + --> $DIR/open-ns-9.rs:5:5 + | +LL | use my_api::utils::get_u32; + | ^^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution + = note: `my_api` could refer to a namespaced crate passed with `--extern` +note: `my_api` could also refer to the module defined here + --> $DIR/open-ns-9.rs:10:9 + | +LL | / pub mod my_api { +LL | | pub mod utils { +LL | | pub fn get_u32() -> u32 { +LL | | 2 +... | +LL | | } + | |_________^ +... +LL | define!(); + | --------- in this macro invocation + = help: use `crate::my_api` to refer to this module unambiguously + = note: this error originates in the macro `define` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. From 9a4b38c916ca758e05a020a550048d4ef47f6a74 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 21 Mar 2026 14:13:00 +0100 Subject: [PATCH 05/11] Add new alias for Guillaume Gomez email address --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index c0333b49f53b2..17232083679c5 100644 --- a/.mailmap +++ b/.mailmap @@ -262,6 +262,7 @@ Guillaume Gomez Guillaume Gomez ggomez Guillaume Gomez Guillaume Gomez Guillaume Gomez Guillaume Gomez +Guillaume Gomez Guillaume Gomez gnzlbg hamidreza kalbasi Hanna Kruppe From b31dc4ab495c0297c4f09324094e9c8e62d52977 Mon Sep 17 00:00:00 2001 From: Usman Akinyemi Date: Sat, 21 Mar 2026 21:45:57 +0530 Subject: [PATCH 06/11] diagnostics: avoid ICE for undeclared generic parameter in impl Avoid an ICE for: struct A; impl A {} The compiler no longer panics and can proceed to emit existing diagnostics. Adds `tests/ui/missing/undeclared-generic-parameter.rs`. Signed-off-by: Usman Akinyemi --- .../rustc_resolve/src/late/diagnostics.rs | 2 +- .../missing/undeclared-generic-parameter.rs | 5 +++ .../undeclared-generic-parameter.stderr | 36 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 tests/ui/missing/undeclared-generic-parameter.rs create mode 100644 tests/ui/missing/undeclared-generic-parameter.stderr diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index e24389e0d74df..713d6eb74bcba 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3381,7 +3381,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { && def_id.is_local() && let Some(local_def_id) = def_id.as_local() && let Some(struct_generics) = self.r.struct_generics.get(&local_def_id) - && let target_param = &struct_generics.params[idx] + && let Some(target_param) = &struct_generics.params.get(idx) && let GenericParamKind::Const { ty, .. } = &target_param.kind && let TyKind::Path(_, path) = &ty.kind { diff --git a/tests/ui/missing/undeclared-generic-parameter.rs b/tests/ui/missing/undeclared-generic-parameter.rs new file mode 100644 index 0000000000000..eebae215c8813 --- /dev/null +++ b/tests/ui/missing/undeclared-generic-parameter.rs @@ -0,0 +1,5 @@ +struct A; +impl A {} +//~^ ERROR cannot find type `B` in this scope +//~| ERROR struct takes 0 generic arguments but 1 generic argument was supplied +fn main() {} diff --git a/tests/ui/missing/undeclared-generic-parameter.stderr b/tests/ui/missing/undeclared-generic-parameter.stderr new file mode 100644 index 0000000000000..101a5790ed4e6 --- /dev/null +++ b/tests/ui/missing/undeclared-generic-parameter.stderr @@ -0,0 +1,36 @@ +error[E0425]: cannot find type `B` in this scope + --> $DIR/undeclared-generic-parameter.rs:2:8 + | +LL | struct A; + | --------- similarly named struct `A` defined here +LL | impl A {} + | ^ + | +help: a struct with a similar name exists + | +LL - impl A {} +LL + impl A {} + | +help: you might be missing a type parameter + | +LL | impl A {} + | +++ + +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/undeclared-generic-parameter.rs:2:6 + | +LL | impl A {} + | ^--- help: remove the unnecessary generics + | | + | expected 0 generic arguments + | +note: struct defined here, with 0 generic parameters + --> $DIR/undeclared-generic-parameter.rs:1:8 + | +LL | struct A; + | ^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0107, E0425. +For more information about an error, try `rustc --explain E0107`. From e0aed9c5f665ff7ee4881e8db68382b454fb994a Mon Sep 17 00:00:00 2001 From: Romain Perier Date: Sat, 21 Mar 2026 19:18:20 +0100 Subject: [PATCH 07/11] Point to the tracking issue for #[diagnostic::on_move] Now that the tracking issue has been opened, point to it. --- compiler/rustc_feature/src/unstable.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index e8ca20d7f5f44..a559211e5d467 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -473,7 +473,7 @@ declare_features! ( /// Allows giving non-const impls custom diagnostic messages if attempted to be used as const (unstable, diagnostic_on_const, "1.93.0", Some(143874)), /// Allows giving on-move borrowck custom diagnostic messages for a type - (unstable, diagnostic_on_move, "CURRENT_RUSTC_VERSION", Some(150935)), + (unstable, diagnostic_on_move, "CURRENT_RUSTC_VERSION", Some(154181)), /// Allows `#[doc(cfg(...))]`. (unstable, doc_cfg, "1.21.0", Some(43781)), /// Allows `#[doc(masked)]`. From 8d072616a5d0c484e9761b0958ece68e8d235fe3 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sat, 16 Mar 2024 15:56:18 -0400 Subject: [PATCH 08/11] Add APIs for dealing with titlecase - `char::is_cased` - `char::is_titlecase` - `char::case` - `char::to_titlecase` --- library/alloc/src/lib.rs | 1 + library/core/src/char/methods.rs | 240 ++++++++++++++++-- library/core/src/char/mod.rs | 83 ++++-- library/core/src/unicode/mod.rs | 4 +- library/core/src/unicode/unicode_data.rs | 82 +++++- library/coretests/tests/char.rs | 57 ++++- library/coretests/tests/lib.rs | 1 + library/coretests/tests/unicode.rs | 34 ++- library/coretests/tests/unicode/test_data.rs | 78 ++++++ .../src/case_mapping.rs | 45 +++- src/tools/unicode-table-generator/src/main.rs | 58 +++-- 11 files changed, 581 insertions(+), 102 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 7ac9cdc3833d3..bcd9e092a310f 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -148,6 +148,7 @@ #![feature(slice_range)] #![feature(std_internals)] #![feature(temporary_niche_types)] +#![feature(titlecase)] #![feature(transmutability)] #![feature(trivial_clone)] #![feature(trusted_fused)] diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 284a3eeb75dfb..e9c3b040dc50b 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -777,12 +777,76 @@ impl char { #[inline] pub fn is_alphabetic(self) -> bool { match self { - 'A'..='Z' | 'a'..='z' => true, + 'a'..='z' | 'A'..='Z' => true, '\0'..='\u{A9}' => false, _ => unicode::Alphabetic(self), } } + /// Returns `true` if this `char` has the `Cased` property. + /// A character is cased if and only if it is uppercase, lowercase, or titlecase. + /// + /// `Cased` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and + /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`]. + /// + /// [Unicode Standard]: https://www.unicode.org/versions/latest/ + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(titlecase)] + /// assert!('A'.is_cased()); + /// assert!('a'.is_cased()); + /// assert!(!'京'.is_cased()); + /// ``` + #[must_use] + #[unstable(feature = "titlecase", issue = "153892")] + #[inline] + pub fn is_cased(self) -> bool { + match self { + 'a'..='z' | 'A'..='Z' => true, + '\0'..='\u{A9}' => false, + _ => unicode::Cased(self), + } + } + + /// Returns the case of this character: + /// [`Some(CharCase::Upper)`][`CharCase::Upper`] if [`self.is_uppercase()`][`char::is_uppercase`], + /// [`Some(CharCase::Lower)`][`CharCase::Lower`] if [`self.is_lowercase()`][`char::is_lowercase`], + /// [`Some(CharCase::Title)`][`CharCase::Title`] if [`self.is_titlecase()`][`char::is_titlecase`], and + /// `None` if [`!self.is_cased()`][`char::is_cased`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(titlecase)] + /// use core::char::CharCase; + /// assert_eq!('a'.case(), Some(CharCase::Lower)); + /// assert_eq!('δ'.case(), Some(CharCase::Lower)); + /// assert_eq!('A'.case(), Some(CharCase::Upper)); + /// assert_eq!('Δ'.case(), Some(CharCase::Upper)); + /// assert_eq!('Dž'.case(), Some(CharCase::Title)); + /// assert_eq!('中'.case(), None); + /// ``` + #[must_use] + #[unstable(feature = "titlecase", issue = "153892")] + #[inline] + pub fn case(self) -> Option { + match self { + 'a'..='z' => Some(CharCase::Lower), + 'A'..='Z' => Some(CharCase::Upper), + '\0'..='\u{A9}' => None, + _ if !unicode::Cased(self) => None, + _ if unicode::Lowercase(self) => Some(CharCase::Lower), + _ if unicode::Uppercase(self) => Some(CharCase::Upper), + _ => Some(CharCase::Title), + } + } + /// Returns `true` if this `char` has the `Lowercase` property. /// /// `Lowercase` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and @@ -825,6 +889,40 @@ impl char { } } + /// Returns `true` if this `char` has the general category for titlecase letters. + /// Conceptually, these characters consist of an uppercase portion followed by a lowercase portion. + /// + /// Titlecase letters (code points with the general category of `Lt`) are described in Chapter 4 + /// (Character Properties) of the [Unicode Standard] and specified in the [Unicode Character + /// Database][ucd] [`UnicodeData.txt`]. + /// + /// [Unicode Standard]: https://www.unicode.org/versions/latest/ + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(titlecase)] + /// assert!('Dž'.is_titlecase()); + /// assert!('ῼ'.is_titlecase()); + /// assert!(!'D'.is_titlecase()); + /// assert!(!'z'.is_titlecase()); + /// assert!(!'中'.is_titlecase()); + /// assert!(!' '.is_titlecase()); + /// ``` + #[must_use] + #[unstable(feature = "titlecase", issue = "153892")] + #[inline] + pub fn is_titlecase(self) -> bool { + match self { + '\0'..='\u{01C4}' => false, + _ => self.is_cased() && !self.is_lowercase() && !self.is_uppercase(), + } + } + /// Returns `true` if this `char` has the `Uppercase` property. /// /// `Uppercase` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and @@ -925,7 +1023,7 @@ impl char { #[inline] pub fn is_alphanumeric(self) -> bool { match self { - '0'..='9' | 'A'..='Z' | 'a'..='z' => true, + 'a'..='z' | 'A'..='Z' | '0'..='9' => true, '\0'..='\u{A9}' => false, _ => unicode::Alphabetic(self) || unicode::N(self), } @@ -976,26 +1074,6 @@ impl char { self > '\u{02FF}' && unicode::Grapheme_Extend(self) } - /// Returns `true` if this `char` has the `Cased` property. - /// - /// `Cased` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and - /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`]. - /// - /// [Unicode Standard]: https://www.unicode.org/versions/latest/ - /// [ucd]: https://www.unicode.org/reports/tr44/ - /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt - #[must_use] - #[inline] - #[doc(hidden)] - #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")] - pub fn is_cased(self) -> bool { - match self { - 'A'..='Z' | 'a'..='z' => true, - '\0'..='\u{A9}' => false, - _ => unicode::Cased(self), - } - } - /// Returns `true` if this `char` has the `Case_Ignorable` property. /// /// `Case_Ignorable` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and @@ -1119,7 +1197,7 @@ impl char { /// // convert into themselves. /// assert_eq!('山'.to_lowercase().to_string(), "山"); /// ``` - #[must_use = "this returns the lowercase character as a new iterator, \ + #[must_use = "this returns the lowercased character as a new iterator, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -1127,9 +1205,115 @@ impl char { ToLowercase(CaseMappingIter::new(conversions::to_lower(self))) } + /// Returns an iterator that yields the titlecase mapping of this `char` as one or more + /// `char`s. + /// + /// This is usually, but not always, equivalent to the uppercase mapping + /// returned by [`Self::to_uppercase`]. Prefer this method when seeking to capitalize + /// Only The First Letter of a word, but use [`Self::to_uppercase`] for ALL CAPS. + /// + /// If this `char` does not have an titlecase mapping, the iterator yields the same `char`. + /// + /// If this `char` has a one-to-one titlecase mapping given by the [Unicode Character + /// Database][ucd] [`UnicodeData.txt`], the iterator yields that `char`. + /// + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt + /// + /// If this `char` requires special considerations (e.g. multiple `char`s) the iterator yields + /// the `char`(s) given by [`SpecialCasing.txt`]. + /// + /// [`SpecialCasing.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt + /// + /// This operation performs an unconditional mapping without tailoring. That is, the conversion + /// is independent of context and language. + /// + /// In the [Unicode Standard], Chapter 4 (Character Properties) discusses case mapping in + /// general and Chapter 3 (Conformance) discusses the default algorithm for case conversion. + /// + /// [Unicode Standard]: https://www.unicode.org/versions/latest/ + /// + /// # Examples + /// + /// As an iterator: + /// + /// ``` + /// #![feature(titlecase)] + /// for c in 'ß'.to_titlecase() { + /// print!("{c}"); + /// } + /// println!(); + /// ``` + /// + /// Using `println!` directly: + /// + /// ``` + /// #![feature(titlecase)] + /// println!("{}", 'ß'.to_titlecase()); + /// ``` + /// + /// Both are equivalent to: + /// + /// ``` + /// println!("Ss"); + /// ``` + /// + /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string): + /// + /// ``` + /// #![feature(titlecase)] + /// assert_eq!('c'.to_titlecase().to_string(), "C"); + /// assert_eq!('dž'.to_titlecase().to_string(), "Dž"); + /// assert_eq!('ῼ'.to_titlecase().to_string(), "ῼ"); + /// + /// // Sometimes the result is more than one character: + /// assert_eq!('ß'.to_titlecase().to_string(), "Ss"); + /// + /// // Characters that do not have separate cased forms + /// // convert into themselves. + /// assert_eq!('山'.to_titlecase().to_string(), "山"); + /// ``` + /// + /// # Note on locale + /// + /// In Turkish and Azeri, the equivalent of 'i' in Latin has five forms instead of two: + /// + /// * 'Dotless': I / ı, sometimes written ï + /// * 'Dotted': İ / i + /// + /// Note that the lowercase dotted 'i' is the same as the Latin. Therefore: + /// + /// ``` + /// #![feature(titlecase)] + /// let upper_i = 'i'.to_titlecase().to_string(); + /// ``` + /// + /// The value of `upper_i` here relies on the language of the text: if we're + /// in `en-US`, it should be `"I"`, but if we're in `tr-TR` or `az-AZ`, it should + /// be `"İ"`. `to_titlecase()` does not take this into account, and so: + /// + /// ``` + /// #![feature(titlecase)] + /// let upper_i = 'i'.to_titlecase().to_string(); + /// + /// assert_eq!(upper_i, "I"); + /// ``` + /// + /// holds across languages. + #[must_use = "this returns the titlecased character as a new iterator, \ + without modifying the original"] + #[unstable(feature = "titlecase", issue = "153892")] + #[inline] + pub fn to_titlecase(self) -> ToTitlecase { + ToTitlecase(CaseMappingIter::new(conversions::to_title(self))) + } + /// Returns an iterator that yields the uppercase mapping of this `char` as one or more /// `char`s. /// + /// Prefer this method when converting a word into ALL CAPS, but consider [`Self::to_titlecase`] + /// instead if you seek to capitalize Only The First Letter. + /// /// If this `char` does not have an uppercase mapping, the iterator yields the same `char`. /// /// If this `char` has a one-to-one uppercase mapping given by the [Unicode Character @@ -1179,9 +1363,11 @@ impl char { /// /// ``` /// assert_eq!('c'.to_uppercase().to_string(), "C"); + /// assert_eq!('dž'.to_uppercase().to_string(), "DŽ"); /// /// // Sometimes the result is more than one character: /// assert_eq!('ſt'.to_uppercase().to_string(), "ST"); + /// assert_eq!('ῼ'.to_uppercase().to_string(), "ΩΙ"); /// /// // Characters that do not have both uppercase and lowercase /// // convert into themselves. @@ -1190,7 +1376,7 @@ impl char { /// /// # Note on locale /// - /// In Turkish, the equivalent of 'i' in Latin has five forms instead of two: + /// In Turkish and Azeri, the equivalent of 'i' in Latin has five forms instead of two: /// /// * 'Dotless': I / ı, sometimes written ï /// * 'Dotted': İ / i @@ -1202,7 +1388,7 @@ impl char { /// ``` /// /// The value of `upper_i` here relies on the language of the text: if we're - /// in `en-US`, it should be `"I"`, but if we're in `tr_TR`, it should + /// in `en-US`, it should be `"I"`, but if we're in `tr-TR` or `az-AZ`, it should /// be `"İ"`. `to_uppercase()` does not take this into account, and so: /// /// ``` @@ -1212,7 +1398,7 @@ impl char { /// ``` /// /// holds across languages. - #[must_use = "this returns the uppercase character as a new iterator, \ + #[must_use = "this returns the uppercased character as a new iterator, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -1455,7 +1641,7 @@ impl char { #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")] #[inline] pub const fn is_ascii_alphabetic(&self) -> bool { - matches!(*self, 'A'..='Z' | 'a'..='z') + matches!(*self, 'a'..='z' | 'A'..='Z') } /// Checks if the value is an ASCII uppercase character: diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs index 82a3f6f916be3..3231c4193064c 100644 --- a/library/core/src/char/mod.rs +++ b/library/core/src/char/mod.rs @@ -363,13 +363,21 @@ impl fmt::Display for EscapeDebug { } macro_rules! casemappingiter_impls { - ($(#[$attr:meta])* $ITER_NAME:ident) => { + ( + #[$stab:meta] + #[$dendstab:meta] + #[$fusedstab:meta] + #[$exactstab:meta] + #[$displaystab:meta] + $(#[$attr:meta])* + $ITER_NAME:ident + ) => { $(#[$attr])* - #[stable(feature = "rust1", since = "1.0.0")] + #[$stab] #[derive(Debug, Clone)] pub struct $ITER_NAME(CaseMappingIter); - #[stable(feature = "rust1", since = "1.0.0")] + #[$stab] impl Iterator for $ITER_NAME { type Item = char; fn next(&mut self) -> Option { @@ -405,7 +413,7 @@ macro_rules! casemappingiter_impls { } } - #[stable(feature = "case_mapping_double_ended", since = "1.59.0")] + #[$dendstab] impl DoubleEndedIterator for $ITER_NAME { fn next_back(&mut self) -> Option { self.0.next_back() @@ -423,10 +431,10 @@ macro_rules! casemappingiter_impls { } } - #[stable(feature = "fused", since = "1.26.0")] + #[$fusedstab] impl FusedIterator for $ITER_NAME {} - #[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")] + #[$exactstab] impl ExactSizeIterator for $ITER_NAME { fn len(&self) -> usize { self.0.len() @@ -453,7 +461,7 @@ macro_rules! casemappingiter_impls { #[unstable(feature = "std_internals", issue = "none")] unsafe impl TrustedRandomAccess for $ITER_NAME {} - #[stable(feature = "char_struct_display", since = "1.16.0")] + #[$displaystab] impl fmt::Display for $ITER_NAME { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -464,23 +472,48 @@ macro_rules! casemappingiter_impls { } casemappingiter_impls! { - /// Returns an iterator that yields the lowercase equivalent of a `char`. + #[stable(feature = "rust1", since = "1.0.0")] + #[stable(feature = "case_mapping_double_ended", since = "1.59.0")] + #[stable(feature = "fused", since = "1.26.0")] + #[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")] + #[stable(feature = "char_struct_display", since = "1.16.0")] + /// Returns an iterator that yields the uppercase equivalent of a `char`. /// - /// This `struct` is created by the [`to_lowercase`] method on [`char`]. See + /// This `struct` is created by the [`to_uppercase`] method on [`char`]. See /// its documentation for more. /// - /// [`to_lowercase`]: char::to_lowercase - ToLowercase + /// [`to_uppercase`]: char::to_uppercase + ToUppercase } casemappingiter_impls! { - /// Returns an iterator that yields the uppercase equivalent of a `char`. + #[unstable(feature = "titlecase", issue = "153892")] + #[unstable(feature = "titlecase", issue = "153892")] + #[unstable(feature = "titlecase", issue = "153892")] + #[unstable(feature = "titlecase", issue = "153892")] + #[unstable(feature = "titlecase", issue = "153892")] + /// Returns an iterator that yields the titlecase equivalent of a `char`. /// - /// This `struct` is created by the [`to_uppercase`] method on [`char`]. See + /// This `struct` is created by the [`to_titlecase`] method on [`char`]. See /// its documentation for more. /// - /// [`to_uppercase`]: char::to_uppercase - ToUppercase + /// [`to_titlecase`]: char::to_titlecase + ToTitlecase +} + +casemappingiter_impls! { + #[stable(feature = "rust1", since = "1.0.0")] + #[stable(feature = "case_mapping_double_ended", since = "1.59.0")] + #[stable(feature = "fused", since = "1.26.0")] + #[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")] + #[stable(feature = "char_struct_display", since = "1.16.0")] + /// Returns an iterator that yields the lowercase equivalent of a `char`. + /// + /// This `struct` is created by the [`to_lowercase`] method on [`char`]. See + /// its documentation for more. + /// + /// [`to_lowercase`]: char::to_lowercase + ToLowercase } #[derive(Debug, Clone)] @@ -603,3 +636,23 @@ impl fmt::Display for TryFromCharError { #[stable(feature = "u8_from_char", since = "1.59.0")] impl Error for TryFromCharError {} + +/// The case of a cased character, +/// as returned by [`char::case`]. +/// +/// Titlecase characters conceptually are composed of an uppercase portion +/// followed by a lowercase portion. +/// The variant discriminants represent this: +/// the most significant bit represents whether the case +/// conceptually starts as uppercase, while the least significant bit +/// represents whether it conceptually ends as uppercase. +#[unstable(feature = "titlecase", issue = "153892")] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum CharCase { + /// Lowercase. Corresponds to the `Lowercase` Unicode property. + Lower = 0b00, + /// Titlecase. Corresponds to the `Titlecase_Letter` Unicode general category. + Title = 0b10, + /// Uppercase. Corresponds to the `Uppercase` Unicode property. + Upper = 0b11, +} diff --git a/library/core/src/unicode/mod.rs b/library/core/src/unicode/mod.rs index 4c220e3ea0129..22a1166fdf168 100644 --- a/library/core/src/unicode/mod.rs +++ b/library/core/src/unicode/mod.rs @@ -4,12 +4,12 @@ // for use in alloc, not re-exported in std. #[rustfmt::skip] -pub use unicode_data::case_ignorable::lookup as Case_Ignorable; -pub use unicode_data::cased::lookup as Cased; pub use unicode_data::conversions; #[rustfmt::skip] pub(crate) use unicode_data::alphabetic::lookup as Alphabetic; +pub(crate) use unicode_data::case_ignorable::lookup as Case_Ignorable; +pub(crate) use unicode_data::cased::lookup as Cased; pub(crate) use unicode_data::grapheme_extend::lookup as Grapheme_Extend; pub(crate) use unicode_data::lowercase::lookup as Lowercase; pub(crate) use unicode_data::n::lookup as N; diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs index dd3712669e500..f602cd5c5b6b3 100644 --- a/library/core/src/unicode/unicode_data.rs +++ b/library/core/src/unicode/unicode_data.rs @@ -9,7 +9,8 @@ // White_Space : 256 bytes, 19 codepoints in 8 ranges (U+000085 - U+003001) using cascading // to_lower : 1112 bytes, 1462 codepoints in 185 ranges (U+0000C0 - U+01E921) using 2-level LUT // to_upper : 1998 bytes, 1554 codepoints in 299 ranges (U+0000B5 - U+01E943) using 2-level LUT -// Total : 9657 bytes +// to_title : 340 bytes, 135 codepoints in 49 ranges (U+0000DF - U+00FB17) using 2-level LUT +// Total : 9997 bytes #[inline(always)] const fn bitset_search< @@ -823,14 +824,10 @@ pub mod conversions { unsafe { char::from_u32_unchecked(((plane as u32) << 16) | (low as u32)) } } - fn lookup(input: char, ascii: char, l1_lut: &L1Lut) -> [char; 3] { - if input.is_ascii() { - return [ascii, '\0', '\0']; - } - + fn lookup(input: char, l1_lut: &L1Lut) -> Option<[char; 3]> { let (input_high, input_low) = deconstruct(input); let Some(l2_lut) = l1_lut.l2_luts.get(input_high as usize) else { - return [input, '\0', '\0']; + return None; }; let idx = l2_lut.singles.binary_search_by(|(range, _)| { @@ -844,6 +841,7 @@ pub mod conversions { Ordering::Equal } }); + if let Ok(idx) = idx { // SAFETY: binary search guarantees that the index is in bounds. let &(range, output_delta) = unsafe { l2_lut.singles.get_unchecked(idx) }; @@ -852,7 +850,7 @@ pub mod conversions { let output_low = input_low.wrapping_add_signed(output_delta); // SAFETY: Table data are guaranteed to be valid Unicode. let output = unsafe { reconstruct(input_high, output_low) }; - return [output, '\0', '\0']; + return Some([output, '\0', '\0']); } }; @@ -861,18 +859,37 @@ pub mod conversions { let &(_, output_lows) = unsafe { l2_lut.multis.get_unchecked(idx) }; // SAFETY: Table data are guaranteed to be valid Unicode. let output = output_lows.map(|output_low| unsafe { reconstruct(input_high, output_low) }); - return output; + return Some(output); }; - [input, '\0', '\0'] + None } pub fn to_lower(c: char) -> [char; 3] { - lookup(c, c.to_ascii_lowercase(), &LOWERCASE_LUT) + // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%253AChanges_When_Lowercased%253A%5D-%5B%253AASCII%253A%5D&abb=on + if c < '\u{C0}' { + return [c.to_ascii_lowercase(), '\0', '\0']; + } + + lookup(c, &LOWERCASE_LUT).unwrap_or([c, '\0', '\0']) } pub fn to_upper(c: char) -> [char; 3] { - lookup(c, c.to_ascii_uppercase(), &UPPERCASE_LUT) + // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%253AChanges_When_Uppercased%253A%5D-%5B%253AASCII%253A%5D&abb=on + if c < '\u{B5}' { + return [c.to_ascii_uppercase(), '\0', '\0']; + } + + lookup(c, &UPPERCASE_LUT).unwrap_or([c, '\0', '\0']) + } + + pub fn to_title(c: char) -> [char; 3] { + // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%253AChanges_When_Titlecased%253A%5D-%5B%253AASCII%253A%5D&abb=on + if c < '\u{B5}' { + return [c.to_ascii_uppercase(), '\0', '\0']; + } + + lookup(c, &TITLECASE_LUT).or_else(|| lookup(c, &UPPERCASE_LUT)).unwrap_or([c, '\0', '\0']) } static LOWERCASE_LUT: L1Lut = L1Lut { @@ -1150,4 +1167,45 @@ pub mod conversions { }, ], }; + + static TITLECASE_LUT: L1Lut = L1Lut { + l2_luts: [ + L2Lut { + singles: &[ // 26 entries, 156 bytes + (Range::singleton(0x01c4), 1), (Range::singleton(0x01c5), 0), + (Range::singleton(0x01c6), -1), (Range::singleton(0x01c7), 1), + (Range::singleton(0x01c8), 0), (Range::singleton(0x01c9), -1), + (Range::singleton(0x01ca), 1), (Range::singleton(0x01cb), 0), + (Range::singleton(0x01cc), -1), (Range::singleton(0x01f1), 1), + (Range::singleton(0x01f2), 0), (Range::singleton(0x01f3), -1), + (Range::step_by_1(0x10d0..=0x10fa), 0), (Range::step_by_1(0x10fd..=0x10ff), 0), + (Range::step_by_1(0x1f80..=0x1f87), 8), (Range::step_by_1(0x1f88..=0x1f8f), 0), + (Range::step_by_1(0x1f90..=0x1f97), 8), (Range::step_by_1(0x1f98..=0x1f9f), 0), + (Range::step_by_1(0x1fa0..=0x1fa7), 8), (Range::step_by_1(0x1fa8..=0x1faf), 0), + (Range::singleton(0x1fb3), 9), (Range::singleton(0x1fbc), 0), (Range::singleton(0x1fc3), 9), + (Range::singleton(0x1fcc), 0), (Range::singleton(0x1ff3), 9), (Range::singleton(0x1ffc), 0), + ], + multis: &[ // 23 entries, 184 bytes + (0x00df, [0x0053, 0x0073, 0x0000]), (0x0587, [0x0535, 0x0582, 0x0000]), + (0x1fb2, [0x1fba, 0x0345, 0x0000]), (0x1fb4, [0x0386, 0x0345, 0x0000]), + (0x1fb7, [0x0391, 0x0342, 0x0345]), (0x1fc2, [0x1fca, 0x0345, 0x0000]), + (0x1fc4, [0x0389, 0x0345, 0x0000]), (0x1fc7, [0x0397, 0x0342, 0x0345]), + (0x1ff2, [0x1ffa, 0x0345, 0x0000]), (0x1ff4, [0x038f, 0x0345, 0x0000]), + (0x1ff7, [0x03a9, 0x0342, 0x0345]), (0xfb00, [0x0046, 0x0066, 0x0000]), + (0xfb01, [0x0046, 0x0069, 0x0000]), (0xfb02, [0x0046, 0x006c, 0x0000]), + (0xfb03, [0x0046, 0x0066, 0x0069]), (0xfb04, [0x0046, 0x0066, 0x006c]), + (0xfb05, [0x0053, 0x0074, 0x0000]), (0xfb06, [0x0053, 0x0074, 0x0000]), + (0xfb13, [0x0544, 0x0576, 0x0000]), (0xfb14, [0x0544, 0x0565, 0x0000]), + (0xfb15, [0x0544, 0x056b, 0x0000]), (0xfb16, [0x054e, 0x0576, 0x0000]), + (0xfb17, [0x0544, 0x056d, 0x0000]), + ], + }, + L2Lut { + singles: &[ // 0 entries, 0 bytes + ], + multis: &[ // 0 entries, 0 bytes + ], + }, + ], + }; } diff --git a/library/coretests/tests/char.rs b/library/coretests/tests/char.rs index f0f6a24429284..aa20585953b7c 100644 --- a/library/coretests/tests/char.rs +++ b/library/coretests/tests/char.rs @@ -1,5 +1,6 @@ +use std::char::{self, CharCase}; +use std::str; use std::str::FromStr; -use std::{char, str}; #[test] fn test_convert() { @@ -39,6 +40,29 @@ fn test_from_str() { assert!(char::from_str("abc").is_err()); } +#[test] +fn test_is_cased() { + assert!('a'.is_cased()); + assert!('ö'.is_cased()); + assert!('ß'.is_cased()); + assert!('Ü'.is_cased()); + assert!('P'.is_cased()); + assert!('ª'.is_cased()); + assert!(!'攂'.is_cased()); +} + +#[test] +fn test_char_case() { + for c in '\0'..='\u{10FFFF}' { + match c.case() { + None => assert!(!c.is_cased()), + Some(CharCase::Lower) => assert!(c.is_lowercase()), + Some(CharCase::Upper) => assert!(c.is_uppercase()), + Some(CharCase::Title) => assert!(c.is_titlecase()), + } + } +} + #[test] fn test_is_lowercase() { assert!('a'.is_lowercase()); @@ -48,6 +72,17 @@ fn test_is_lowercase() { assert!(!'P'.is_lowercase()); } +#[test] +fn test_is_titlecase() { + assert!('Dž'.is_titlecase()); + assert!('ᾨ'.is_titlecase()); + assert!(!'h'.is_titlecase()); + assert!(!'ä'.is_titlecase()); + assert!(!'ß'.is_titlecase()); + assert!(!'Ö'.is_titlecase()); + assert!(!'T'.is_titlecase()); +} + #[test] fn test_is_uppercase() { assert!(!'h'.is_uppercase()); @@ -57,6 +92,26 @@ fn test_is_uppercase() { assert!('T'.is_uppercase()); } +#[test] +fn titlecase_fast_path() { + for c in '\0'..='\u{01C4}' { + assert!(!(c.is_cased() && !c.is_lowercase() && !c.is_uppercase())) + } +} + +#[test] +fn at_most_one_case() { + for c in '\0'..='\u{10FFFF}' { + assert_eq!( + !c.is_cased() as u8 + + c.is_lowercase() as u8 + + c.is_uppercase() as u8 + + c.is_titlecase() as u8, + 1 + ); + } +} + #[test] fn test_is_whitespace() { assert!(' '.is_whitespace()); diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 72112f8b01133..5f7039641dae3 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -111,6 +111,7 @@ #![feature(step_trait)] #![feature(str_internals)] #![feature(strict_provenance_lints)] +#![feature(titlecase)] #![feature(trusted_len)] #![feature(trusted_random_access)] #![feature(try_blocks)] diff --git a/library/coretests/tests/unicode.rs b/library/coretests/tests/unicode.rs index 1fae74f0f11ef..a8a221db8f955 100644 --- a/library/coretests/tests/unicode.rs +++ b/library/coretests/tests/unicode.rs @@ -27,17 +27,21 @@ fn test_boolean_property(ranges: &[RangeInclusive], lookup: fn(char) -> bo } #[track_caller] -fn test_case_mapping(ranges: &[(char, [char; 3])], lookup: fn(char) -> [char; 3]) { +fn test_case_mapping( + ranges: &[(char, [char; 3])], + lookup: fn(char) -> [char; 3], + fallback: fn(char) -> [char; 3], +) { let mut start = '\u{80}'; for &(key, val) in ranges { for c in start..key { - assert_eq!(lookup(c), [c, '\0', '\0'], "{c:?}"); + assert_eq!(lookup(c), fallback(c), "{c:?}"); } assert_eq!(lookup(key), val, "{key:?}"); start = char::from_u32(key as u32 + 1).unwrap(); } for c in start..=char::MAX { - assert_eq!(lookup(c), [c, '\0', '\0'], "{c:?}"); + assert_eq!(lookup(c), fallback(c), "{c:?}"); } } @@ -45,6 +49,7 @@ fn test_case_mapping(ranges: &[(char, [char; 3])], lookup: fn(char) -> [char; 3] #[cfg_attr(miri, ignore)] // Miri is too slow fn alphabetic() { test_boolean_property(test_data::ALPHABETIC, unicode_data::alphabetic::lookup); + test_boolean_property(test_data::ALPHABETIC, char::is_alphabetic); } #[test] @@ -57,6 +62,7 @@ fn case_ignorable() { #[cfg_attr(miri, ignore)] // Miri is too slow fn cased() { test_boolean_property(test_data::CASED, unicode_data::cased::lookup); + test_boolean_property(test_data::CASED, char::is_cased); } #[test] @@ -69,34 +75,52 @@ fn grapheme_extend() { #[cfg_attr(miri, ignore)] // Miri is too slow fn lowercase() { test_boolean_property(test_data::LOWERCASE, unicode_data::lowercase::lookup); + test_boolean_property(test_data::LOWERCASE, char::is_lowercase); } #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn n() { test_boolean_property(test_data::N, unicode_data::n::lookup); + test_boolean_property(test_data::N, char::is_numeric); } #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn uppercase() { test_boolean_property(test_data::UPPERCASE, unicode_data::uppercase::lookup); + test_boolean_property(test_data::UPPERCASE, char::is_uppercase); } #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn white_space() { test_boolean_property(test_data::WHITE_SPACE, unicode_data::white_space::lookup); + test_boolean_property(test_data::WHITE_SPACE, char::is_whitespace); } #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn to_lowercase() { - test_case_mapping(test_data::TO_LOWER, unicode_data::conversions::to_lower); + test_case_mapping(test_data::TO_LOWER, unicode_data::conversions::to_lower, |c| { + [c, '\0', '\0'] + }); } #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn to_uppercase() { - test_case_mapping(test_data::TO_UPPER, unicode_data::conversions::to_upper); + test_case_mapping(test_data::TO_UPPER, unicode_data::conversions::to_upper, |c| { + [c, '\0', '\0'] + }); +} + +#[test] +#[cfg_attr(miri, ignore)] // Miri is too slow +fn to_titlecase() { + test_case_mapping( + test_data::TO_TITLE, + unicode_data::conversions::to_title, + unicode_data::conversions::to_upper, + ); } diff --git a/library/coretests/tests/unicode/test_data.rs b/library/coretests/tests/unicode/test_data.rs index cfc695475b1f8..3071aedcae07a 100644 --- a/library/coretests/tests/unicode/test_data.rs +++ b/library/coretests/tests/unicode/test_data.rs @@ -2900,3 +2900,81 @@ pub(super) static TO_UPPER: &[(char, [char; 3]); 1554] = &[ ('\u{1e942}', ['\u{1e920}', '\u{0}', '\u{0}']), ('\u{1e943}', ['\u{1e921}', '\u{0}', '\u{0}']), ]; + +#[rustfmt::skip] +pub(super) static TO_TITLE: &[(char, [char; 3]); 135] = &[ + ('\u{df}', ['S', 's', '\u{0}']), ('\u{1c4}', ['\u{1c5}', '\u{0}', '\u{0}']), + ('\u{1c5}', ['\u{1c5}', '\u{0}', '\u{0}']), ('\u{1c6}', ['\u{1c5}', '\u{0}', '\u{0}']), + ('\u{1c7}', ['\u{1c8}', '\u{0}', '\u{0}']), ('\u{1c8}', ['\u{1c8}', '\u{0}', '\u{0}']), + ('\u{1c9}', ['\u{1c8}', '\u{0}', '\u{0}']), ('\u{1ca}', ['\u{1cb}', '\u{0}', '\u{0}']), + ('\u{1cb}', ['\u{1cb}', '\u{0}', '\u{0}']), ('\u{1cc}', ['\u{1cb}', '\u{0}', '\u{0}']), + ('\u{1f1}', ['\u{1f2}', '\u{0}', '\u{0}']), ('\u{1f2}', ['\u{1f2}', '\u{0}', '\u{0}']), + ('\u{1f3}', ['\u{1f2}', '\u{0}', '\u{0}']), ('\u{587}', ['\u{535}', '\u{582}', '\u{0}']), + ('\u{10d0}', ['\u{10d0}', '\u{0}', '\u{0}']), ('\u{10d1}', ['\u{10d1}', '\u{0}', '\u{0}']), + ('\u{10d2}', ['\u{10d2}', '\u{0}', '\u{0}']), ('\u{10d3}', ['\u{10d3}', '\u{0}', '\u{0}']), + ('\u{10d4}', ['\u{10d4}', '\u{0}', '\u{0}']), ('\u{10d5}', ['\u{10d5}', '\u{0}', '\u{0}']), + ('\u{10d6}', ['\u{10d6}', '\u{0}', '\u{0}']), ('\u{10d7}', ['\u{10d7}', '\u{0}', '\u{0}']), + ('\u{10d8}', ['\u{10d8}', '\u{0}', '\u{0}']), ('\u{10d9}', ['\u{10d9}', '\u{0}', '\u{0}']), + ('\u{10da}', ['\u{10da}', '\u{0}', '\u{0}']), ('\u{10db}', ['\u{10db}', '\u{0}', '\u{0}']), + ('\u{10dc}', ['\u{10dc}', '\u{0}', '\u{0}']), ('\u{10dd}', ['\u{10dd}', '\u{0}', '\u{0}']), + ('\u{10de}', ['\u{10de}', '\u{0}', '\u{0}']), ('\u{10df}', ['\u{10df}', '\u{0}', '\u{0}']), + ('\u{10e0}', ['\u{10e0}', '\u{0}', '\u{0}']), ('\u{10e1}', ['\u{10e1}', '\u{0}', '\u{0}']), + ('\u{10e2}', ['\u{10e2}', '\u{0}', '\u{0}']), ('\u{10e3}', ['\u{10e3}', '\u{0}', '\u{0}']), + ('\u{10e4}', ['\u{10e4}', '\u{0}', '\u{0}']), ('\u{10e5}', ['\u{10e5}', '\u{0}', '\u{0}']), + ('\u{10e6}', ['\u{10e6}', '\u{0}', '\u{0}']), ('\u{10e7}', ['\u{10e7}', '\u{0}', '\u{0}']), + ('\u{10e8}', ['\u{10e8}', '\u{0}', '\u{0}']), ('\u{10e9}', ['\u{10e9}', '\u{0}', '\u{0}']), + ('\u{10ea}', ['\u{10ea}', '\u{0}', '\u{0}']), ('\u{10eb}', ['\u{10eb}', '\u{0}', '\u{0}']), + ('\u{10ec}', ['\u{10ec}', '\u{0}', '\u{0}']), ('\u{10ed}', ['\u{10ed}', '\u{0}', '\u{0}']), + ('\u{10ee}', ['\u{10ee}', '\u{0}', '\u{0}']), ('\u{10ef}', ['\u{10ef}', '\u{0}', '\u{0}']), + ('\u{10f0}', ['\u{10f0}', '\u{0}', '\u{0}']), ('\u{10f1}', ['\u{10f1}', '\u{0}', '\u{0}']), + ('\u{10f2}', ['\u{10f2}', '\u{0}', '\u{0}']), ('\u{10f3}', ['\u{10f3}', '\u{0}', '\u{0}']), + ('\u{10f4}', ['\u{10f4}', '\u{0}', '\u{0}']), ('\u{10f5}', ['\u{10f5}', '\u{0}', '\u{0}']), + ('\u{10f6}', ['\u{10f6}', '\u{0}', '\u{0}']), ('\u{10f7}', ['\u{10f7}', '\u{0}', '\u{0}']), + ('\u{10f8}', ['\u{10f8}', '\u{0}', '\u{0}']), ('\u{10f9}', ['\u{10f9}', '\u{0}', '\u{0}']), + ('\u{10fa}', ['\u{10fa}', '\u{0}', '\u{0}']), ('\u{10fd}', ['\u{10fd}', '\u{0}', '\u{0}']), + ('\u{10fe}', ['\u{10fe}', '\u{0}', '\u{0}']), ('\u{10ff}', ['\u{10ff}', '\u{0}', '\u{0}']), + ('\u{1f80}', ['\u{1f88}', '\u{0}', '\u{0}']), ('\u{1f81}', ['\u{1f89}', '\u{0}', '\u{0}']), + ('\u{1f82}', ['\u{1f8a}', '\u{0}', '\u{0}']), ('\u{1f83}', ['\u{1f8b}', '\u{0}', '\u{0}']), + ('\u{1f84}', ['\u{1f8c}', '\u{0}', '\u{0}']), ('\u{1f85}', ['\u{1f8d}', '\u{0}', '\u{0}']), + ('\u{1f86}', ['\u{1f8e}', '\u{0}', '\u{0}']), ('\u{1f87}', ['\u{1f8f}', '\u{0}', '\u{0}']), + ('\u{1f88}', ['\u{1f88}', '\u{0}', '\u{0}']), ('\u{1f89}', ['\u{1f89}', '\u{0}', '\u{0}']), + ('\u{1f8a}', ['\u{1f8a}', '\u{0}', '\u{0}']), ('\u{1f8b}', ['\u{1f8b}', '\u{0}', '\u{0}']), + ('\u{1f8c}', ['\u{1f8c}', '\u{0}', '\u{0}']), ('\u{1f8d}', ['\u{1f8d}', '\u{0}', '\u{0}']), + ('\u{1f8e}', ['\u{1f8e}', '\u{0}', '\u{0}']), ('\u{1f8f}', ['\u{1f8f}', '\u{0}', '\u{0}']), + ('\u{1f90}', ['\u{1f98}', '\u{0}', '\u{0}']), ('\u{1f91}', ['\u{1f99}', '\u{0}', '\u{0}']), + ('\u{1f92}', ['\u{1f9a}', '\u{0}', '\u{0}']), ('\u{1f93}', ['\u{1f9b}', '\u{0}', '\u{0}']), + ('\u{1f94}', ['\u{1f9c}', '\u{0}', '\u{0}']), ('\u{1f95}', ['\u{1f9d}', '\u{0}', '\u{0}']), + ('\u{1f96}', ['\u{1f9e}', '\u{0}', '\u{0}']), ('\u{1f97}', ['\u{1f9f}', '\u{0}', '\u{0}']), + ('\u{1f98}', ['\u{1f98}', '\u{0}', '\u{0}']), ('\u{1f99}', ['\u{1f99}', '\u{0}', '\u{0}']), + ('\u{1f9a}', ['\u{1f9a}', '\u{0}', '\u{0}']), ('\u{1f9b}', ['\u{1f9b}', '\u{0}', '\u{0}']), + ('\u{1f9c}', ['\u{1f9c}', '\u{0}', '\u{0}']), ('\u{1f9d}', ['\u{1f9d}', '\u{0}', '\u{0}']), + ('\u{1f9e}', ['\u{1f9e}', '\u{0}', '\u{0}']), ('\u{1f9f}', ['\u{1f9f}', '\u{0}', '\u{0}']), + ('\u{1fa0}', ['\u{1fa8}', '\u{0}', '\u{0}']), ('\u{1fa1}', ['\u{1fa9}', '\u{0}', '\u{0}']), + ('\u{1fa2}', ['\u{1faa}', '\u{0}', '\u{0}']), ('\u{1fa3}', ['\u{1fab}', '\u{0}', '\u{0}']), + ('\u{1fa4}', ['\u{1fac}', '\u{0}', '\u{0}']), ('\u{1fa5}', ['\u{1fad}', '\u{0}', '\u{0}']), + ('\u{1fa6}', ['\u{1fae}', '\u{0}', '\u{0}']), ('\u{1fa7}', ['\u{1faf}', '\u{0}', '\u{0}']), + ('\u{1fa8}', ['\u{1fa8}', '\u{0}', '\u{0}']), ('\u{1fa9}', ['\u{1fa9}', '\u{0}', '\u{0}']), + ('\u{1faa}', ['\u{1faa}', '\u{0}', '\u{0}']), ('\u{1fab}', ['\u{1fab}', '\u{0}', '\u{0}']), + ('\u{1fac}', ['\u{1fac}', '\u{0}', '\u{0}']), ('\u{1fad}', ['\u{1fad}', '\u{0}', '\u{0}']), + ('\u{1fae}', ['\u{1fae}', '\u{0}', '\u{0}']), ('\u{1faf}', ['\u{1faf}', '\u{0}', '\u{0}']), + ('\u{1fb2}', ['\u{1fba}', '\u{345}', '\u{0}']), + ('\u{1fb3}', ['\u{1fbc}', '\u{0}', '\u{0}']), ('\u{1fb4}', ['\u{386}', '\u{345}', '\u{0}']), + ('\u{1fb7}', ['\u{391}', '\u{342}', '\u{345}']), + ('\u{1fbc}', ['\u{1fbc}', '\u{0}', '\u{0}']), + ('\u{1fc2}', ['\u{1fca}', '\u{345}', '\u{0}']), + ('\u{1fc3}', ['\u{1fcc}', '\u{0}', '\u{0}']), ('\u{1fc4}', ['\u{389}', '\u{345}', '\u{0}']), + ('\u{1fc7}', ['\u{397}', '\u{342}', '\u{345}']), + ('\u{1fcc}', ['\u{1fcc}', '\u{0}', '\u{0}']), + ('\u{1ff2}', ['\u{1ffa}', '\u{345}', '\u{0}']), + ('\u{1ff3}', ['\u{1ffc}', '\u{0}', '\u{0}']), ('\u{1ff4}', ['\u{38f}', '\u{345}', '\u{0}']), + ('\u{1ff7}', ['\u{3a9}', '\u{342}', '\u{345}']), + ('\u{1ffc}', ['\u{1ffc}', '\u{0}', '\u{0}']), ('\u{fb00}', ['F', 'f', '\u{0}']), + ('\u{fb01}', ['F', 'i', '\u{0}']), ('\u{fb02}', ['F', 'l', '\u{0}']), + ('\u{fb03}', ['F', 'f', 'i']), ('\u{fb04}', ['F', 'f', 'l']), + ('\u{fb05}', ['S', 't', '\u{0}']), ('\u{fb06}', ['S', 't', '\u{0}']), + ('\u{fb13}', ['\u{544}', '\u{576}', '\u{0}']), + ('\u{fb14}', ['\u{544}', '\u{565}', '\u{0}']), + ('\u{fb15}', ['\u{544}', '\u{56b}', '\u{0}']), + ('\u{fb16}', ['\u{54e}', '\u{576}', '\u{0}']), + ('\u{fb17}', ['\u{544}', '\u{56d}', '\u{0}']), +]; diff --git a/src/tools/unicode-table-generator/src/case_mapping.rs b/src/tools/unicode-table-generator/src/case_mapping.rs index 6345cb8ef2532..b7b385542ef53 100644 --- a/src/tools/unicode-table-generator/src/case_mapping.rs +++ b/src/tools/unicode-table-generator/src/case_mapping.rs @@ -48,7 +48,7 @@ use std::ops::RangeInclusive; use crate::fmt_helpers::Hex; use crate::{UnicodeData, fmt_list}; -pub(crate) fn generate_case_mapping(data: &UnicodeData) -> (String, [(String, usize); 2]) { +pub(crate) fn generate_case_mapping(data: &UnicodeData) -> (String, [(String, usize); 3]) { let mut file = String::new(); file.push_str("\n\n"); @@ -59,7 +59,10 @@ pub(crate) fn generate_case_mapping(data: &UnicodeData) -> (String, [(String, us file.push_str("\n\n"); let (upper_tables, upper_desc, upper_size) = generate_tables("UPPER", &data.to_upper); file.push_str(&upper_tables); - (file, [(lower_desc, lower_size), (upper_desc, upper_size)]) + file.push_str("\n\n"); + let (title_tables, title_desc, title_size) = generate_tables("TITLE", &data.to_title); + file.push_str(&title_tables); + (file, [(lower_desc, lower_size), (upper_desc, upper_size), (title_desc, title_size)]) } // So far, only planes 0 and 1 (Basic Multilingual Plane and Supplementary @@ -336,14 +339,10 @@ unsafe fn reconstruct(plane: u16, low: u16) -> char { unsafe { char::from_u32_unchecked(((plane as u32) << 16) | (low as u32)) } } -fn lookup(input: char, ascii: char, l1_lut: &L1Lut) -> [char; 3] { - if input.is_ascii() { - return [ascii, '\0', '\0']; - } - +fn lookup(input: char, l1_lut: &L1Lut) -> Option<[char; 3]> { let (input_high, input_low) = deconstruct(input); let Some(l2_lut) = l1_lut.l2_luts.get(input_high as usize) else { - return [input, '\0', '\0']; + return None; }; let idx = l2_lut.singles.binary_search_by(|(range, _)| { @@ -357,6 +356,7 @@ fn lookup(input: char, ascii: char, l1_lut: &L1Lut) -> [char; 3] { Ordering::Equal } }); + if let Ok(idx) = idx { // SAFETY: binary search guarantees that the index is in bounds. let &(range, output_delta) = unsafe { l2_lut.singles.get_unchecked(idx) }; @@ -365,7 +365,7 @@ fn lookup(input: char, ascii: char, l1_lut: &L1Lut) -> [char; 3] { let output_low = input_low.wrapping_add_signed(output_delta); // SAFETY: Table data are guaranteed to be valid Unicode. let output = unsafe { reconstruct(input_high, output_low) }; - return [output, '\0', '\0']; + return Some([output, '\0', '\0']); } }; @@ -374,17 +374,36 @@ fn lookup(input: char, ascii: char, l1_lut: &L1Lut) -> [char; 3] { let &(_, output_lows) = unsafe { l2_lut.multis.get_unchecked(idx) }; // SAFETY: Table data are guaranteed to be valid Unicode. let output = output_lows.map(|output_low| unsafe { reconstruct(input_high, output_low) }); - return output; + return Some(output); }; - [input, '\0', '\0'] + None } pub fn to_lower(c: char) -> [char; 3] { - lookup(c, c.to_ascii_lowercase(), &LOWERCASE_LUT) + // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%253AChanges_When_Lowercased%253A%5D-%5B%253AASCII%253A%5D&abb=on + if c < '\u{C0}' { + return [c.to_ascii_lowercase(), '\0', '\0']; + } + + lookup(c, &LOWERCASE_LUT).unwrap_or([c, '\0', '\0']) } pub fn to_upper(c: char) -> [char; 3] { - lookup(c, c.to_ascii_uppercase(), &UPPERCASE_LUT) + // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%253AChanges_When_Uppercased%253A%5D-%5B%253AASCII%253A%5D&abb=on + if c < '\u{B5}' { + return [c.to_ascii_uppercase(), '\0', '\0']; + } + + lookup(c, &UPPERCASE_LUT).unwrap_or([c, '\0', '\0']) +} + +pub fn to_title(c: char) -> [char; 3] { + // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%253AChanges_When_Titlecased%253A%5D-%5B%253AASCII%253A%5D&abb=on + if c < '\u{B5}' { + return [c.to_ascii_uppercase(), '\0', '\0']; + } + + lookup(c, &TITLECASE_LUT).or_else(|| lookup(c, &UPPERCASE_LUT)).unwrap_or([c, '\0', '\0']) } "; diff --git a/src/tools/unicode-table-generator/src/main.rs b/src/tools/unicode-table-generator/src/main.rs index 4e7c40efc1234..cdd137ff56a52 100644 --- a/src/tools/unicode-table-generator/src/main.rs +++ b/src/tools/unicode-table-generator/src/main.rs @@ -100,32 +100,25 @@ static PROPERTIES: &[&str] = &[ struct UnicodeData { ranges: Vec<(&'static str, Vec>)>, + /// Only stores mappings that are not to self to_upper: BTreeMap, + /// Only stores mappings that differ from `to_upper` + to_title: BTreeMap, + /// Only stores mappings that are not to self to_lower: BTreeMap, } -fn to_mapping(origin: u32, codepoints: Vec) -> Option<[u32; 3]> { - let mut a = None; - let mut b = None; - let mut c = None; - - for codepoint in codepoints { - if origin == codepoint.value() { - return None; - } - - if a.is_none() { - a = Some(codepoint.value()); - } else if b.is_none() { - b = Some(codepoint.value()); - } else if c.is_none() { - c = Some(codepoint.value()); - } else { - panic!("more than 3 mapped codepoints") - } +fn to_mapping( + if_different_from: &[ucd_parse::Codepoint], + codepoints: &[ucd_parse::Codepoint], +) -> Option<[u32; 3]> { + if codepoints == if_different_from { + return None; } - Some([a.unwrap(), b.unwrap_or(0), c.unwrap_or(0)]) + let mut ret = [ucd_parse::Codepoint::default(); 3]; + ret[0..codepoints.len()].copy_from_slice(codepoints); + Some(ret.map(ucd_parse::Codepoint::value)) } static UNICODE_DIRECTORY: &str = "unicode-downloads"; @@ -145,8 +138,7 @@ fn load_data() -> UnicodeData { } } - let mut to_lower = BTreeMap::new(); - let mut to_upper = BTreeMap::new(); + let [mut to_lower, mut to_upper, mut to_title] = [const { BTreeMap::new() }; 3]; for row in ucd_parse::UnicodeDataExpander::new( ucd_parse::parse::<_, ucd_parse::UnicodeData>(&UNICODE_DIRECTORY).unwrap(), ) { @@ -172,6 +164,11 @@ fn load_data() -> UnicodeData { { to_upper.insert(row.codepoint.value(), [mapped.value(), 0, 0]); } + if let Some(mapped) = row.simple_titlecase_mapping + && Some(mapped) != row.simple_uppercase_mapping + { + to_title.insert(row.codepoint.value(), [mapped.value(), 0, 0]); + } } for row in ucd_parse::parse::<_, ucd_parse::SpecialCaseMapping>(&UNICODE_DIRECTORY).unwrap() { @@ -181,12 +178,15 @@ fn load_data() -> UnicodeData { } let key = row.codepoint.value(); - if let Some(lower) = to_mapping(key, row.lowercase) { + if let Some(lower) = to_mapping(&[row.codepoint], &row.lowercase) { to_lower.insert(key, lower); } - if let Some(upper) = to_mapping(key, row.uppercase) { + if let Some(upper) = to_mapping(&[row.codepoint], &row.uppercase) { to_upper.insert(key, upper); } + if let Some(title) = to_mapping(&row.uppercase, &row.titlecase) { + to_title.insert(key, title); + } } // Filter out ASCII codepoints. @@ -207,7 +207,7 @@ fn load_data() -> UnicodeData { .collect(); properties.sort_by_key(|p| p.0); - UnicodeData { ranges: properties, to_lower, to_upper } + UnicodeData { ranges: properties, to_lower, to_title, to_upper } } fn main() { @@ -259,7 +259,7 @@ fn main() { total_bytes += emitter.bytes_used; } let (conversions, sizes) = case_mapping::generate_case_mapping(&unicode_data); - for (name, (desc, size)) in ["to_lower", "to_upper"].iter().zip(sizes) { + for (name, (desc, size)) in ["to_lower", "to_upper", "to_title"].iter().zip(sizes) { table_file.push_str(&format!("// {:16}: {:5} bytes, {desc}\n", name, size,)); total_bytes += size; } @@ -369,7 +369,11 @@ pub(super) static {prop_upper}: &[RangeInclusive; {is_true_len}] = &[{is_t .unwrap(); } - for (name, lut) in ["TO_LOWER", "TO_UPPER"].iter().zip([&data.to_lower, &data.to_upper]) { + for (name, lut) in ["TO_LOWER", "TO_UPPER", "TO_TITLE"].iter().zip([ + &data.to_lower, + &data.to_upper, + &data.to_title, + ]) { let lut = lut .iter() .map(|(key, values)| { From 9b0be7857af8e355523b1db8b9e24acfd9be7db1 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Sat, 21 Mar 2026 12:38:32 +0000 Subject: [PATCH 09/11] allow `incomplete_features` in most UI tests --- src/tools/compiletest/src/runtest.rs | 9 +- .../type-const-in-array-len-wrong-type.rs | 3 - .../type-const-in-array-len-wrong-type.stderr | 29 +---- .../type-const-in-array-len.rs | 2 - .../type-const-in-array-len.stderr | 19 ---- .../hr-do-not-blame-outlives-static-ice.rs | 1 - ...hr-do-not-blame-outlives-static-ice.stderr | 17 +-- .../variance-computation-requires-equality.rs | 1 - ...iance-computation-requires-equality.stderr | 11 -- .../defaults-specialization.rs | 1 - .../defaults-specialization.stderr | 42 +++----- .../async-drop/foreign-fundamental.rs | 1 - .../async-drop/foreign-fundamental.stderr | 15 +-- .../dyn/mut-is-pointer-like.stderr | 11 +- tests/ui/async-await/dyn/works.stderr | 11 +- tests/ui/async-await/dyn/wrong-size.stderr | 11 +- .../ui/borrowck/generic_const_early_param.rs | 1 - .../borrowck/generic_const_early_param.stderr | 17 +-- tests/ui/closures/binder/const-bound.rs | 1 - tests/ui/closures/binder/const-bound.stderr | 15 +-- tests/ui/closures/binder/type-bound-2.rs | 1 - tests/ui/closures/binder/type-bound-2.stderr | 13 +-- tests/ui/closures/binder/type-bound.rs | 1 - tests/ui/closures/binder/type-bound.stderr | 13 +-- .../freeze-on-polymorphic-projection.rs | 1 - .../freeze-on-polymorphic-projection.stderr | 12 --- .../coherence-doesnt-use-infcx-evaluate.rs | 1 - ...coherence-doesnt-use-infcx-evaluate.stderr | 12 --- .../coherence-inherited-assoc-ty-cycle-err.rs | 1 - ...erence-inherited-assoc-ty-cycle-err.stderr | 16 +-- .../regions-in-canonical.rs | 1 - .../regions-in-canonical.stderr | 11 -- tests/ui/consts/escaping-bound-var.rs | 1 - tests/ui/consts/escaping-bound-var.stderr | 15 +-- tests/ui/consts/issue-104396.rs | 1 - tests/ui/consts/issue-104396.stderr | 11 -- .../consts/refs_check_const_eq-issue-88384.rs | 1 - .../refs_check_const_eq-issue-88384.stderr | 15 +-- .../generic-associated-const.rs | 1 - .../generic-associated-const.stderr | 17 +-- tests/ui/consts/trait_specialization.rs | 2 +- tests/ui/consts/trait_specialization.stderr | 12 --- tests/ui/contracts/incomplete-feature.rs | 1 + tests/ui/contracts/incomplete-feature.stderr | 8 +- tests/ui/error-codes/E0520.rs | 1 - tests/ui/error-codes/E0520.stderr | 14 +-- tests/ui/error-codes/E0771.rs | 1 - tests/ui/error-codes/E0771.stderr | 13 +-- ...e-effective-target-features.default.stderr | 8 +- ...e-effective-target-features.feature.stderr | 14 ++- .../feature-gate-effective-target-features.rs | 1 + .../feature-gate-unsafe_fields.rs | 2 +- ...eature-gate-unsafe_fields.with_gate.stderr | 6 +- .../issue-87429-specialization.rs | 1 - .../issue-87429-specialization.stderr | 16 +-- .../recover-incorrect-impl-restriction.rs | 1 + ...ncorrect-impl-restriction.with_gate.stderr | 20 ++-- ...rrect-impl-restriction.without_gate.stderr | 24 ++--- .../trait-alias-cannot-be-impl-restricted.rs | 1 + ...cannot-be-impl-restricted.with_gate.stderr | 32 +++--- ...not-be-impl-restricted.without_gate.stderr | 38 +++---- tests/ui/impl-trait/equality-rpass.rs | 2 +- tests/ui/impl-trait/equality-rpass.stderr | 12 --- tests/ui/impl-trait/equality.rs | 2 +- tests/ui/impl-trait/equality.stderr | 12 +-- tests/ui/impl-trait/equality2.rs | 2 +- tests/ui/impl-trait/equality2.stderr | 12 +-- .../in-trait/alias-bounds-when-not-wf.rs | 1 - .../in-trait/alias-bounds-when-not-wf.stderr | 25 ++--- .../ui/layout/gce-rigid-const-in-array-len.rs | 2 +- .../gce-rigid-const-in-array-len.stderr | 11 +- .../ui/lazy-type-alias/bad-lazy-type-alias.rs | 1 - .../bad-lazy-type-alias.stderr | 15 +-- .../coerce-behind-lazy.current.stderr | 11 -- .../coerce-behind-lazy.next.stderr | 11 -- .../ui/lazy-type-alias/coerce-behind-lazy.rs | 1 - tests/ui/lazy-type-alias/enum-variant.rs | 1 - tests/ui/lazy-type-alias/enum-variant.stderr | 11 -- ...lap-doesnt-conflict-with-specialization.rs | 2 +- ...doesnt-conflict-with-specialization.stderr | 12 --- .../assoc/assoc-static-semantic-fail.rs | 1 - .../assoc/assoc-static-semantic-fail.stderr | 60 +++++------ tests/ui/parser/default.rs | 1 - tests/ui/parser/default.stderr | 20 +--- ...efaultness-invalid-places-fail-semantic.rs | 2 +- ...ltness-invalid-places-fail-semantic.stderr | 12 +-- .../empty-types.exhaustive_patterns.stderr | 100 +++++++++--------- .../usefulness/empty-types.never_pats.stderr | 97 ++++++++--------- .../usefulness/empty-types.normal.stderr | 86 +++++++-------- tests/ui/pattern/usefulness/empty-types.rs | 1 - .../pin-ergonomics/coerce-non-pointer-pin.rs | 1 - .../coerce-non-pointer-pin.stderr | 11 -- .../never-pattern-is-a-read.rs | 1 - .../never-pattern-is-a-read.stderr | 13 +-- .../dont-assume-err-is-yes-issue-126377.rs | 1 - ...dont-assume-err-is-yes-issue-126377.stderr | 17 +-- .../non_scalar_alignment_value.rs | 1 - .../non_scalar_alignment_value.stderr | 19 +--- tests/ui/unsafe-binders/binder-sized-crit.rs | 1 - .../unsafe-binders/binder-sized-crit.stderr | 11 -- tests/ui/unsafe-binders/expr.rs | 1 - tests/ui/unsafe-binders/expr.stderr | 11 -- .../ui/unsafe-binders/lifetime-resolution.rs | 1 - .../unsafe-binders/lifetime-resolution.stderr | 15 +-- tests/ui/unsafe-binders/mismatch.rs | 1 - tests/ui/unsafe-binders/mismatch.stderr | 21 ++-- tests/ui/unsafe-binders/moves.rs | 1 - tests/ui/unsafe-binders/moves.stderr | 19 +--- tests/ui/unsafe-binders/simple.rs | 1 - tests/ui/unsafe-binders/simple.stderr | 11 -- tests/ui/unsafe-binders/type-mismatch.rs | 1 - tests/ui/unsafe-binders/type-mismatch.stderr | 15 +-- .../unsafe-binders-debuginfo.rs | 1 - .../unsafe-binders-debuginfo.stderr | 11 -- 114 files changed, 374 insertions(+), 917 deletions(-) delete mode 100644 tests/ui/associated-consts/type-const-in-array-len.stderr delete mode 100644 tests/ui/associated-inherent-types/variance-computation-requires-equality.stderr delete mode 100644 tests/ui/codegen/freeze-on-polymorphic-projection.stderr delete mode 100644 tests/ui/coherence/coherence-doesnt-use-infcx-evaluate.stderr delete mode 100644 tests/ui/coherence/negative-coherence/regions-in-canonical.stderr delete mode 100644 tests/ui/consts/issue-104396.stderr delete mode 100644 tests/ui/consts/trait_specialization.stderr delete mode 100644 tests/ui/impl-trait/equality-rpass.stderr delete mode 100644 tests/ui/lazy-type-alias/coerce-behind-lazy.current.stderr delete mode 100644 tests/ui/lazy-type-alias/coerce-behind-lazy.next.stderr delete mode 100644 tests/ui/lazy-type-alias/enum-variant.stderr delete mode 100644 tests/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr delete mode 100644 tests/ui/pin-ergonomics/coerce-non-pointer-pin.stderr delete mode 100644 tests/ui/unsafe-binders/binder-sized-crit.stderr delete mode 100644 tests/ui/unsafe-binders/expr.stderr delete mode 100644 tests/ui/unsafe-binders/simple.stderr delete mode 100644 tests/ui/unsafe-binders/unsafe-binders-debuginfo.stderr diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index b584d14b0c9ff..40e6c4e593b19 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1919,8 +1919,15 @@ impl<'test> TestCx<'test> { compiler.args(&["-A", "unused", "-W", "unused_attributes"]); } - // Allow tests to use internal features. + // Allow tests to use internal and incomplete features. compiler.args(&["-A", "internal_features"]); + // FIXME(#154168); temporarily exclude some directories to make the transition easier + if !input_file + .iter() + .any(|p| p == "traits" || p == "specialization" || p == "const-generics") + { + compiler.args(&["-A", "incomplete_features"]); + } // Allow tests to have unused parens and braces. // Add #![deny(unused_parens, unused_braces)] to the test file if you want to diff --git a/tests/ui/associated-consts/type-const-in-array-len-wrong-type.rs b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.rs index cb0b8a102eb47..c260ab1ee584d 100644 --- a/tests/ui/associated-consts/type-const-in-array-len-wrong-type.rs +++ b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.rs @@ -1,9 +1,6 @@ #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete #![feature(min_generic_const_args)] -//~^ WARN the feature `min_generic_const_args` is incomplete #![feature(inherent_associated_types)] -//~^ WARN the feature `inherent_associated_types` is incomplete struct OnDiskDirEntry<'a>(&'a ()); diff --git a/tests/ui/associated-consts/type-const-in-array-len-wrong-type.stderr b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.stderr index b69a1b7fd7dec..a90b1f666067d 100644 --- a/tests/ui/associated-consts/type-const-in-array-len-wrong-type.stderr +++ b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.stderr @@ -1,35 +1,10 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-const-in-array-len-wrong-type.rs:1:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-const-in-array-len-wrong-type.rs:3:12 - | -LL | #![feature(min_generic_const_args)] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #132980 for more information - -warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-const-in-array-len-wrong-type.rs:5:12 - | -LL | #![feature(inherent_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #8995 for more information - error: the constant `2` is not of type `usize` - --> $DIR/type-const-in-array-len-wrong-type.rs:13:26 + --> $DIR/type-const-in-array-len-wrong-type.rs:10:26 | LL | fn lfn_contents() -> [char; Self::LFN_FRAGMENT_LEN] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `i64` | = note: the length of array `[char; 2]` must be type `usize` -error: aborting due to 1 previous error; 3 warnings emitted +error: aborting due to 1 previous error diff --git a/tests/ui/associated-consts/type-const-in-array-len.rs b/tests/ui/associated-consts/type-const-in-array-len.rs index d33eacaade2df..7a809cefe9f75 100644 --- a/tests/ui/associated-consts/type-const-in-array-len.rs +++ b/tests/ui/associated-consts/type-const-in-array-len.rs @@ -1,9 +1,7 @@ //@ check-pass #![feature(min_generic_const_args)] -//~^ WARN the feature `min_generic_const_args` is incomplete #![feature(inherent_associated_types)] -//~^ WARN the feature `inherent_associated_types` is incomplete // Test case from #138226: generic impl with multiple type parameters struct Foo(A, B); diff --git a/tests/ui/associated-consts/type-const-in-array-len.stderr b/tests/ui/associated-consts/type-const-in-array-len.stderr deleted file mode 100644 index 546995d13a0a8..0000000000000 --- a/tests/ui/associated-consts/type-const-in-array-len.stderr +++ /dev/null @@ -1,19 +0,0 @@ -warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-const-in-array-len.rs:3:12 - | -LL | #![feature(min_generic_const_args)] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #132980 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-const-in-array-len.rs:5:12 - | -LL | #![feature(inherent_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #8995 for more information - -warning: 2 warnings emitted - diff --git a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.rs b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.rs index e5c1f47b9e02b..27b3b93f071da 100644 --- a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.rs +++ b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.rs @@ -2,7 +2,6 @@ // Regression test for #146467. #![feature(inherent_associated_types)] -//~^ WARN the feature `inherent_associated_types` is incomplete struct Foo(T); diff --git a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr index 4c0726d4ddca9..b06add2f5db5d 100644 --- a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr +++ b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr @@ -1,20 +1,11 @@ -warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/hr-do-not-blame-outlives-static-ice.rs:4:12 - | -LL | #![feature(inherent_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #8995 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates - --> $DIR/hr-do-not-blame-outlives-static-ice.rs:9:6 + --> $DIR/hr-do-not-blame-outlives-static-ice.rs:8:6 | LL | impl<'a> Foo { | ^^ unconstrained lifetime parameter error[E0308]: mismatched types - --> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:11 + --> $DIR/hr-do-not-blame-outlives-static-ice.rs:13:11 | LL | fn foo(_: for<'a> fn(Foo::Assoc)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other @@ -23,12 +14,12 @@ LL | fn foo(_: for<'a> fn(Foo::Assoc)) {} found struct `Foo fn(&'a ())>` error: higher-ranked subtype error - --> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:1 + --> $DIR/hr-do-not-blame-outlives-static-ice.rs:13:1 | LL | fn foo(_: for<'a> fn(Foo::Assoc)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors Some errors have detailed explanations: E0207, E0308. For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/associated-inherent-types/variance-computation-requires-equality.rs b/tests/ui/associated-inherent-types/variance-computation-requires-equality.rs index 3f726792b4a11..b7f8586e31e8a 100644 --- a/tests/ui/associated-inherent-types/variance-computation-requires-equality.rs +++ b/tests/ui/associated-inherent-types/variance-computation-requires-equality.rs @@ -1,7 +1,6 @@ //@ check-pass #![feature(inherent_associated_types)] -//~^ WARN the feature `inherent_associated_types` is incomplete struct D { a: T diff --git a/tests/ui/associated-inherent-types/variance-computation-requires-equality.stderr b/tests/ui/associated-inherent-types/variance-computation-requires-equality.stderr deleted file mode 100644 index 93064f551abdc..0000000000000 --- a/tests/ui/associated-inherent-types/variance-computation-requires-equality.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/variance-computation-requires-equality.rs:3:12 - | -LL | #![feature(inherent_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #8995 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/associated-types/defaults-specialization.rs b/tests/ui/associated-types/defaults-specialization.rs index 553705b2a4fab..d0ed718b83923 100644 --- a/tests/ui/associated-types/defaults-specialization.rs +++ b/tests/ui/associated-types/defaults-specialization.rs @@ -1,7 +1,6 @@ //! Tests the interaction of associated type defaults and specialization. #![feature(associated_type_defaults, specialization)] -//~^ WARN the feature `specialization` is incomplete trait Tr { type Ty = u8; diff --git a/tests/ui/associated-types/defaults-specialization.stderr b/tests/ui/associated-types/defaults-specialization.stderr index d22d9ce659a76..2e880a7d50ade 100644 --- a/tests/ui/associated-types/defaults-specialization.stderr +++ b/tests/ui/associated-types/defaults-specialization.stderr @@ -1,21 +1,11 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/defaults-specialization.rs:3:38 - | -LL | #![feature(associated_type_defaults, specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0053]: method `make` has an incompatible type for trait - --> $DIR/defaults-specialization.rs:19:18 + --> $DIR/defaults-specialization.rs:18:18 | LL | fn make() -> u8 { 0 } | ^^ expected associated type, found `u8` | note: type in trait - --> $DIR/defaults-specialization.rs:9:18 + --> $DIR/defaults-specialization.rs:8:18 | LL | fn make() -> Self::Ty { | ^^^^^^^^ @@ -28,7 +18,7 @@ LL + fn make() -> as Tr>::Ty { 0 } | error[E0053]: method `make` has an incompatible type for trait - --> $DIR/defaults-specialization.rs:35:18 + --> $DIR/defaults-specialization.rs:34:18 | LL | default type Ty = bool; | --------------- associated type is `default` and may be overridden @@ -37,7 +27,7 @@ LL | fn make() -> bool { true } | ^^^^ expected associated type, found `bool` | note: type in trait - --> $DIR/defaults-specialization.rs:9:18 + --> $DIR/defaults-specialization.rs:8:18 | LL | fn make() -> Self::Ty { | ^^^^^^^^ @@ -50,7 +40,7 @@ LL + fn make() -> as Tr>::Ty { true } | error[E0308]: mismatched types - --> $DIR/defaults-specialization.rs:10:9 + --> $DIR/defaults-specialization.rs:9:9 | LL | type Ty = u8; | ------- associated type defaults can't be assumed inside the trait defining them @@ -64,7 +54,7 @@ LL | 0u8 found type `u8` error[E0308]: mismatched types - --> $DIR/defaults-specialization.rs:26:29 + --> $DIR/defaults-specialization.rs:25:29 | LL | fn make() -> Self::Ty { 0u8 } | -------- ^^^ expected associated type, found `u8` @@ -79,7 +69,7 @@ LL | fn make() -> Self::Ty { 0u8 } see issue #152409 for more information error[E0308]: mismatched types - --> $DIR/defaults-specialization.rs:44:29 + --> $DIR/defaults-specialization.rs:43:29 | LL | default type Ty = bool; | --------------- associated type is `default` and may be overridden @@ -95,7 +85,7 @@ LL | fn make() -> Self::Ty { true } see issue #152409 for more information error[E0308]: mismatched types - --> $DIR/defaults-specialization.rs:87:32 + --> $DIR/defaults-specialization.rs:86:32 | LL | let _: as Tr>::Ty = 0u8; | ----------------- ^^^ expected associated type, found `u8` @@ -105,13 +95,13 @@ LL | let _: as Tr>::Ty = 0u8; = note: expected associated type ` as Tr>::Ty` found type `u8` help: a method is available that returns ` as Tr>::Ty` - --> $DIR/defaults-specialization.rs:9:5 + --> $DIR/defaults-specialization.rs:8:5 | LL | fn make() -> Self::Ty { | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make` error[E0308]: mismatched types - --> $DIR/defaults-specialization.rs:88:32 + --> $DIR/defaults-specialization.rs:87:32 | LL | let _: as Tr>::Ty = true; | ----------------- ^^^^ expected associated type, found `bool` @@ -121,7 +111,7 @@ LL | let _: as Tr>::Ty = true; = note: expected associated type ` as Tr>::Ty` found type `bool` help: a method is available that returns ` as Tr>::Ty` - --> $DIR/defaults-specialization.rs:9:5 + --> $DIR/defaults-specialization.rs:8:5 | LL | fn make() -> Self::Ty { | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make` @@ -129,7 +119,7 @@ LL | fn make() -> Self::Ty { see issue #152409 for more information error[E0308]: mismatched types - --> $DIR/defaults-specialization.rs:89:33 + --> $DIR/defaults-specialization.rs:88:33 | LL | let _: as Tr>::Ty = 0u8; | ------------------ ^^^ expected associated type, found `u8` @@ -139,13 +129,13 @@ LL | let _: as Tr>::Ty = 0u8; = note: expected associated type ` as Tr>::Ty` found type `u8` help: a method is available that returns ` as Tr>::Ty` - --> $DIR/defaults-specialization.rs:9:5 + --> $DIR/defaults-specialization.rs:8:5 | LL | fn make() -> Self::Ty { | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make` error[E0308]: mismatched types - --> $DIR/defaults-specialization.rs:90:33 + --> $DIR/defaults-specialization.rs:89:33 | LL | let _: as Tr>::Ty = true; | ------------------ ^^^^ expected associated type, found `bool` @@ -155,14 +145,14 @@ LL | let _: as Tr>::Ty = true; = note: expected associated type ` as Tr>::Ty` found type `bool` help: a method is available that returns ` as Tr>::Ty` - --> $DIR/defaults-specialization.rs:9:5 + --> $DIR/defaults-specialization.rs:8:5 | LL | fn make() -> Self::Ty { | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make` = note: the associated type ` as Tr>::Ty` is defined as `bool` in the implementation, but the where-bound `B2<()>` shadows this definition see issue #152409 for more information -error: aborting due to 9 previous errors; 1 warning emitted +error: aborting due to 9 previous errors Some errors have detailed explanations: E0053, E0308. For more information about an error, try `rustc --explain E0053`. diff --git a/tests/ui/async-await/async-drop/foreign-fundamental.rs b/tests/ui/async-await/async-drop/foreign-fundamental.rs index 1c192fccd9f0c..44be20449469a 100644 --- a/tests/ui/async-await/async-drop/foreign-fundamental.rs +++ b/tests/ui/async-await/async-drop/foreign-fundamental.rs @@ -1,7 +1,6 @@ //@ edition: 2018 #![feature(async_drop)] -//~^ WARN the feature `async_drop` is incomplete use std::future::AsyncDrop; use std::pin::Pin; diff --git a/tests/ui/async-await/async-drop/foreign-fundamental.stderr b/tests/ui/async-await/async-drop/foreign-fundamental.stderr index 7b52329ac99d1..78bfdf66901a8 100644 --- a/tests/ui/async-await/async-drop/foreign-fundamental.stderr +++ b/tests/ui/async-await/async-drop/foreign-fundamental.stderr @@ -1,24 +1,15 @@ -warning: the feature `async_drop` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/foreign-fundamental.rs:3:12 - | -LL | #![feature(async_drop)] - | ^^^^^^^^^^ - | - = note: see issue #126482 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0120]: the `AsyncDrop` trait may only be implemented for local structs, enums, and unions - --> $DIR/foreign-fundamental.rs:11:20 + --> $DIR/foreign-fundamental.rs:10:20 | LL | impl AsyncDrop for &Foo { | ^^^^ must be a struct, enum, or union in the current crate error[E0120]: the `AsyncDrop` trait may only be implemented for local structs, enums, and unions - --> $DIR/foreign-fundamental.rs:16:20 + --> $DIR/foreign-fundamental.rs:15:20 | LL | impl AsyncDrop for Pin { | ^^^^^^^^ must be a struct, enum, or union in the current crate -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0120`. diff --git a/tests/ui/async-await/dyn/mut-is-pointer-like.stderr b/tests/ui/async-await/dyn/mut-is-pointer-like.stderr index 6689539ff453a..0f390522620ee 100644 --- a/tests/ui/async-await/dyn/mut-is-pointer-like.stderr +++ b/tests/ui/async-await/dyn/mut-is-pointer-like.stderr @@ -1,12 +1,3 @@ -warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/mut-is-pointer-like.rs:6:12 - | -LL | #![feature(async_fn_in_dyn_trait)] - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #133119 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0038]: the trait `AsyncTrait` is not dyn compatible --> $DIR/mut-is-pointer-like.rs:35:29 | @@ -24,6 +15,6 @@ LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output; | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` = help: consider moving `async_dispatch` to another trait -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/async-await/dyn/works.stderr b/tests/ui/async-await/dyn/works.stderr index 338479d8b70a9..c7d0d14d70e77 100644 --- a/tests/ui/async-await/dyn/works.stderr +++ b/tests/ui/async-await/dyn/works.stderr @@ -1,12 +1,3 @@ -warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/works.rs:6:12 - | -LL | #![feature(async_fn_in_dyn_trait)] - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #133119 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0038]: the trait `AsyncTrait` is not dyn compatible --> $DIR/works.rs:27:21 | @@ -24,6 +15,6 @@ LL | async fn async_dispatch(&self); = help: consider moving `async_dispatch` to another trait = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/async-await/dyn/wrong-size.stderr b/tests/ui/async-await/dyn/wrong-size.stderr index a465f91f62af0..4835c173f0d7d 100644 --- a/tests/ui/async-await/dyn/wrong-size.stderr +++ b/tests/ui/async-await/dyn/wrong-size.stderr @@ -1,12 +1,3 @@ -warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/wrong-size.rs:4:12 - | -LL | #![feature(async_fn_in_dyn_trait)] - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #133119 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0038]: the trait `AsyncTrait` is not dyn compatible --> $DIR/wrong-size.rs:21:17 | @@ -24,6 +15,6 @@ LL | async fn async_dispatch(&self); = help: consider moving `async_dispatch` to another trait = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/borrowck/generic_const_early_param.rs b/tests/ui/borrowck/generic_const_early_param.rs index 0d07b6869f122..e5fab5919793d 100644 --- a/tests/ui/borrowck/generic_const_early_param.rs +++ b/tests/ui/borrowck/generic_const_early_param.rs @@ -1,5 +1,4 @@ #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete struct DataWrapper<'static> { //~^ ERROR invalid lifetime parameter name: `'static` diff --git a/tests/ui/borrowck/generic_const_early_param.stderr b/tests/ui/borrowck/generic_const_early_param.stderr index 6447f92aba853..a9ee438388148 100644 --- a/tests/ui/borrowck/generic_const_early_param.stderr +++ b/tests/ui/borrowck/generic_const_early_param.stderr @@ -1,11 +1,11 @@ error[E0262]: invalid lifetime parameter name: `'static` - --> $DIR/generic_const_early_param.rs:4:20 + --> $DIR/generic_const_early_param.rs:3:20 | LL | struct DataWrapper<'static> { | ^^^^^^^ 'static is a reserved lifetime name error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/generic_const_early_param.rs:6:12 + --> $DIR/generic_const_early_param.rs:5:12 | LL | data: &'a [u8; Self::SIZE], | ^^ undeclared lifetime @@ -16,7 +16,7 @@ LL | struct DataWrapper<'a, 'static> { | +++ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/generic_const_early_param.rs:10:18 + --> $DIR/generic_const_early_param.rs:9:18 | LL | impl DataWrapper<'a> { | ^^ undeclared lifetime @@ -26,16 +26,7 @@ help: consider introducing lifetime `'a` here LL | impl<'a> DataWrapper<'a> { | ++++ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/generic_const_early_param.rs:1:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors Some errors have detailed explanations: E0261, E0262. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/closures/binder/const-bound.rs b/tests/ui/closures/binder/const-bound.rs index 10d869fcc8512..e6984ed6d5592 100644 --- a/tests/ui/closures/binder/const-bound.rs +++ b/tests/ui/closures/binder/const-bound.rs @@ -1,5 +1,4 @@ #![feature(closure_lifetime_binder, non_lifetime_binders)] -//~^ WARN is incomplete and may not be safe to use fn main() { for || -> () {}; diff --git a/tests/ui/closures/binder/const-bound.stderr b/tests/ui/closures/binder/const-bound.stderr index b805879f7fab5..a57788072b0b4 100644 --- a/tests/ui/closures/binder/const-bound.stderr +++ b/tests/ui/closures/binder/const-bound.stderr @@ -1,23 +1,14 @@ error: late-bound const parameters cannot be used currently - --> $DIR/const-bound.rs:5:15 + --> $DIR/const-bound.rs:4:15 | LL | for || -> () {}; | ^ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-bound.rs:1:37 - | -LL | #![feature(closure_lifetime_binder, non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 for more information - = note: `#[warn(incomplete_features)]` on by default - error: late-bound const parameter not allowed on closures - --> $DIR/const-bound.rs:5:9 + --> $DIR/const-bound.rs:4:9 | LL | for || -> () {}; | ^^^^^^^^^^^^ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors diff --git a/tests/ui/closures/binder/type-bound-2.rs b/tests/ui/closures/binder/type-bound-2.rs index f4edcdaa9ca9f..064fbf975d453 100644 --- a/tests/ui/closures/binder/type-bound-2.rs +++ b/tests/ui/closures/binder/type-bound-2.rs @@ -1,5 +1,4 @@ #![feature(closure_lifetime_binder, non_lifetime_binders)] -//~^ WARN is incomplete and may not be safe to use fn main() { for || -> () {}; diff --git a/tests/ui/closures/binder/type-bound-2.stderr b/tests/ui/closures/binder/type-bound-2.stderr index 6609b326f19a5..6fd7d576dd70e 100644 --- a/tests/ui/closures/binder/type-bound-2.stderr +++ b/tests/ui/closures/binder/type-bound-2.stderr @@ -1,17 +1,8 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-bound-2.rs:1:37 - | -LL | #![feature(closure_lifetime_binder, non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 for more information - = note: `#[warn(incomplete_features)]` on by default - error: late-bound type parameter not allowed on closures - --> $DIR/type-bound-2.rs:5:9 + --> $DIR/type-bound-2.rs:4:9 | LL | for || -> () {}; | ^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error diff --git a/tests/ui/closures/binder/type-bound.rs b/tests/ui/closures/binder/type-bound.rs index 59a3353f4965e..9fc60b30167bb 100644 --- a/tests/ui/closures/binder/type-bound.rs +++ b/tests/ui/closures/binder/type-bound.rs @@ -1,5 +1,4 @@ #![feature(closure_lifetime_binder, non_lifetime_binders)] -//~^ WARN is incomplete and may not be safe to use fn main() { for || -> T {}; diff --git a/tests/ui/closures/binder/type-bound.stderr b/tests/ui/closures/binder/type-bound.stderr index 22431130a5d4a..11dc3288fe871 100644 --- a/tests/ui/closures/binder/type-bound.stderr +++ b/tests/ui/closures/binder/type-bound.stderr @@ -1,17 +1,8 @@ -warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-bound.rs:1:37 - | -LL | #![feature(closure_lifetime_binder, non_lifetime_binders)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #108185 for more information - = note: `#[warn(incomplete_features)]` on by default - error: late-bound type parameter not allowed on closures - --> $DIR/type-bound.rs:5:9 + --> $DIR/type-bound.rs:4:9 | LL | for || -> T {}; | ^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error diff --git a/tests/ui/codegen/freeze-on-polymorphic-projection.rs b/tests/ui/codegen/freeze-on-polymorphic-projection.rs index f382a3780fcf7..4744fa580b379 100644 --- a/tests/ui/codegen/freeze-on-polymorphic-projection.rs +++ b/tests/ui/codegen/freeze-on-polymorphic-projection.rs @@ -2,7 +2,6 @@ //@ compile-flags: -Copt-level=1 --crate-type=lib #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete pub unsafe trait Storage { type Handle; diff --git a/tests/ui/codegen/freeze-on-polymorphic-projection.stderr b/tests/ui/codegen/freeze-on-polymorphic-projection.stderr deleted file mode 100644 index 903cb2ff6aa98..0000000000000 --- a/tests/ui/codegen/freeze-on-polymorphic-projection.stderr +++ /dev/null @@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/freeze-on-polymorphic-projection.rs:4:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/coherence/coherence-doesnt-use-infcx-evaluate.rs b/tests/ui/coherence/coherence-doesnt-use-infcx-evaluate.rs index 7e53695f987e2..a3dc9b5628fc8 100644 --- a/tests/ui/coherence/coherence-doesnt-use-infcx-evaluate.rs +++ b/tests/ui/coherence/coherence-doesnt-use-infcx-evaluate.rs @@ -5,7 +5,6 @@ // since they are using a different infcx which doesn't preserve the intercrate flag. #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete trait Assoc { type Output; diff --git a/tests/ui/coherence/coherence-doesnt-use-infcx-evaluate.stderr b/tests/ui/coherence/coherence-doesnt-use-infcx-evaluate.stderr deleted file mode 100644 index 56eb21cd20f2f..0000000000000 --- a/tests/ui/coherence/coherence-doesnt-use-infcx-evaluate.stderr +++ /dev/null @@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/coherence-doesnt-use-infcx-evaluate.rs:7:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs b/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs index d74d3a2a52351..7f0e5472c3c2e 100644 --- a/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs +++ b/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs @@ -4,7 +4,6 @@ // // No we expect to run into a more user-friendly cycle error instead. #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete trait Trait { type Assoc; } //~^ ERROR E0391 diff --git a/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr b/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr index 9f813d6d5716a..3d4d19197baf4 100644 --- a/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr +++ b/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr @@ -1,27 +1,17 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:6:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0391]: cycle detected when building specialization graph of trait `Trait` - --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:9:1 + --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:8:1 | LL | trait Trait { type Assoc; } | ^^^^^^^^^^^^^^ | = note: ...which immediately requires building specialization graph of trait `Trait` again note: cycle used when coherence checking all impls of trait `Trait` - --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:9:1 + --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:8:1 | LL | trait Trait { type Assoc; } | ^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/coherence/negative-coherence/regions-in-canonical.rs b/tests/ui/coherence/negative-coherence/regions-in-canonical.rs index f0424e724344b..ff3999f83f6d0 100644 --- a/tests/ui/coherence/negative-coherence/regions-in-canonical.rs +++ b/tests/ui/coherence/negative-coherence/regions-in-canonical.rs @@ -1,7 +1,6 @@ //@ check-pass #![feature(adt_const_params, unsized_const_params)] -//~^ WARN the feature `unsized_const_params` is incomplete #![feature(with_negative_coherence, negative_impls)] pub trait A {} diff --git a/tests/ui/coherence/negative-coherence/regions-in-canonical.stderr b/tests/ui/coherence/negative-coherence/regions-in-canonical.stderr deleted file mode 100644 index 720449152945d..0000000000000 --- a/tests/ui/coherence/negative-coherence/regions-in-canonical.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/regions-in-canonical.rs:3:30 - | -LL | #![feature(adt_const_params, unsized_const_params)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #95174 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/consts/escaping-bound-var.rs b/tests/ui/consts/escaping-bound-var.rs index a538d607d6ca5..03162c74882d4 100644 --- a/tests/ui/consts/escaping-bound-var.rs +++ b/tests/ui/consts/escaping-bound-var.rs @@ -1,5 +1,4 @@ #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete fn test<'a>( _: &'a (), diff --git a/tests/ui/consts/escaping-bound-var.stderr b/tests/ui/consts/escaping-bound-var.stderr index bb0d285f4d06c..046c58bd23b34 100644 --- a/tests/ui/consts/escaping-bound-var.stderr +++ b/tests/ui/consts/escaping-bound-var.stderr @@ -1,14 +1,5 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/escaping-bound-var.rs:1:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 for more information - = note: `#[warn(incomplete_features)]` on by default - error: cannot capture late-bound lifetime in constant - --> $DIR/escaping-bound-var.rs:7:13 + --> $DIR/escaping-bound-var.rs:6:13 | LL | fn test<'a>( | -- lifetime defined here @@ -17,7 +8,7 @@ LL | let x: &'a (); | ^^ error[E0308]: mismatched types - --> $DIR/escaping-bound-var.rs:6:6 + --> $DIR/escaping-bound-var.rs:5:6 | LL | fn test<'a>( | ---- implicitly returns `()` as its body has no tail or `return` expression @@ -33,6 +24,6 @@ LL | | }] { 1 }]`, found `()` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/issue-104396.rs b/tests/ui/consts/issue-104396.rs index f44abc359d670..dc0789eaf6558 100644 --- a/tests/ui/consts/issue-104396.rs +++ b/tests/ui/consts/issue-104396.rs @@ -2,7 +2,6 @@ //@ check-pass #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete #[inline(always)] fn from_fn_1 f32>(mut f: F) -> [f32; N] { diff --git a/tests/ui/consts/issue-104396.stderr b/tests/ui/consts/issue-104396.stderr deleted file mode 100644 index 5856bee09a3fc..0000000000000 --- a/tests/ui/consts/issue-104396.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-104396.rs:4:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/consts/refs_check_const_eq-issue-88384.rs b/tests/ui/consts/refs_check_const_eq-issue-88384.rs index 46cb627517173..506bec349eba6 100644 --- a/tests/ui/consts/refs_check_const_eq-issue-88384.rs +++ b/tests/ui/consts/refs_check_const_eq-issue-88384.rs @@ -1,6 +1,5 @@ #![feature(fn_traits)] #![feature(adt_const_params, unsized_const_params)] -//~^ WARNING the feature `unsized_const_params` is incomplete #[derive(PartialEq, Eq)] struct CompileTimeSettings { diff --git a/tests/ui/consts/refs_check_const_eq-issue-88384.stderr b/tests/ui/consts/refs_check_const_eq-issue-88384.stderr index 62c5c52764115..ac4cb059ea194 100644 --- a/tests/ui/consts/refs_check_const_eq-issue-88384.stderr +++ b/tests/ui/consts/refs_check_const_eq-issue-88384.stderr @@ -1,14 +1,5 @@ -warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/refs_check_const_eq-issue-88384.rs:2:30 - | -LL | #![feature(adt_const_params, unsized_const_params)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #95174 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0741]: `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter - --> $DIR/refs_check_const_eq-issue-88384.rs:10:21 + --> $DIR/refs_check_const_eq-issue-88384.rs:9:21 | LL | struct Foo; | ^^^^^^^^^^^^^^^^^^^ @@ -20,7 +11,7 @@ LL | struct CompileTimeSettings { | error[E0741]: `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter - --> $DIR/refs_check_const_eq-issue-88384.rs:13:15 + --> $DIR/refs_check_const_eq-issue-88384.rs:12:15 | LL | impl Foo { | ^^^^^^^^^^^^^^^^^^^ @@ -31,6 +22,6 @@ LL + #[derive(ConstParamTy)] LL | struct CompileTimeSettings { | -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0741`. diff --git a/tests/ui/consts/static-default-lifetime/generic-associated-const.rs b/tests/ui/consts/static-default-lifetime/generic-associated-const.rs index 721920bd810cb..8fabaa43f5a27 100644 --- a/tests/ui/consts/static-default-lifetime/generic-associated-const.rs +++ b/tests/ui/consts/static-default-lifetime/generic-associated-const.rs @@ -1,6 +1,5 @@ #![deny(elided_lifetimes_in_associated_constant)] #![feature(generic_const_items)] -//~^ WARN the feature `generic_const_items` is incomplete struct A; impl A { diff --git a/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr b/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr index 3680ef61e0c4c..fe858d685f7fa 100644 --- a/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr +++ b/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/generic-associated-const.rs:15:29 + --> $DIR/generic-associated-const.rs:14:29 | LL | const GAC_LIFETIME<'a>: &str = ""; | ^ expected named lifetime parameter @@ -9,23 +9,14 @@ help: consider using the `'a` lifetime LL | const GAC_LIFETIME<'a>: &'a str = ""; | ++ -warning: the feature `generic_const_items` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/generic-associated-const.rs:2:12 - | -LL | #![feature(generic_const_items)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #113521 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `&` without an explicit lifetime name cannot be used here - --> $DIR/generic-associated-const.rs:8:29 + --> $DIR/generic-associated-const.rs:7:29 | LL | const GAC_LIFETIME<'a>: &str = ""; | ^ | note: cannot automatically infer `'static` because of other lifetimes in scope - --> $DIR/generic-associated-const.rs:8:24 + --> $DIR/generic-associated-const.rs:7:24 | LL | const GAC_LIFETIME<'a>: &str = ""; | ^^ @@ -41,6 +32,6 @@ help: use the `'static` lifetime LL | const GAC_LIFETIME<'a>: &'static str = ""; | +++++++ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/consts/trait_specialization.rs b/tests/ui/consts/trait_specialization.rs index 1360fabd1fe11..1ea56b5a44531 100644 --- a/tests/ui/consts/trait_specialization.rs +++ b/tests/ui/consts/trait_specialization.rs @@ -4,7 +4,7 @@ // Tests that specialization does not cause optimizations running on polymorphic MIR to resolve // to a `default` implementation. -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Marker {} diff --git a/tests/ui/consts/trait_specialization.stderr b/tests/ui/consts/trait_specialization.stderr deleted file mode 100644 index ce52cf17b89e6..0000000000000 --- a/tests/ui/consts/trait_specialization.stderr +++ /dev/null @@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait_specialization.rs:7:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/incomplete-feature.rs b/tests/ui/contracts/incomplete-feature.rs index f1351e2f87e34..c10774b251ab4 100644 --- a/tests/ui/contracts/incomplete-feature.rs +++ b/tests/ui/contracts/incomplete-feature.rs @@ -4,6 +4,7 @@ // This test specifically checks that the [incomplete_features] warning is // emitted when the `contracts` feature gate is enabled, so that it can be // marked as `expect`ed in other tests in order to reduce duplication. +#![warn(incomplete_features)] #![feature(contracts)] //~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; diff --git a/tests/ui/contracts/incomplete-feature.stderr b/tests/ui/contracts/incomplete-feature.stderr index 7683926df073a..137b13fb834f8 100644 --- a/tests/ui/contracts/incomplete-feature.stderr +++ b/tests/ui/contracts/incomplete-feature.stderr @@ -1,11 +1,15 @@ warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/incomplete-feature.rs:7:12 + --> $DIR/incomplete-feature.rs:8:12 | LL | #![feature(contracts)] | ^^^^^^^^^ | = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default +note: the lint level is defined here + --> $DIR/incomplete-feature.rs:7:9 + | +LL | #![warn(incomplete_features)] + | ^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted diff --git a/tests/ui/error-codes/E0520.rs b/tests/ui/error-codes/E0520.rs index ead78b7ffa2c4..b746ca63590ec 100644 --- a/tests/ui/error-codes/E0520.rs +++ b/tests/ui/error-codes/E0520.rs @@ -1,5 +1,4 @@ #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete trait SpaceLlama { fn fly(&self); diff --git a/tests/ui/error-codes/E0520.stderr b/tests/ui/error-codes/E0520.stderr index 83319203023ff..c47b3e77c77a5 100644 --- a/tests/ui/error-codes/E0520.stderr +++ b/tests/ui/error-codes/E0520.stderr @@ -1,15 +1,5 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/E0520.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0520]: `fly` specializes an item from a parent `impl`, but that item is not marked `default` - --> $DIR/E0520.rs:17:5 + --> $DIR/E0520.rs:16:5 | LL | impl SpaceLlama for T { | ------------------------------- parent `impl` is here @@ -19,6 +9,6 @@ LL | default fn fly(&self) {} | = note: to specialize, `fly` in the parent `impl` must be marked `default` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0520`. diff --git a/tests/ui/error-codes/E0771.rs b/tests/ui/error-codes/E0771.rs index a932c5ef9815d..6d86d4a54e780 100644 --- a/tests/ui/error-codes/E0771.rs +++ b/tests/ui/error-codes/E0771.rs @@ -1,5 +1,4 @@ #![feature(adt_const_params, unsized_const_params)] -//~^ WARN the feature `unsized_const_params` is incomplete fn function_with_str<'a, const STRING: &'a str>() {} //~ ERROR E0770 diff --git a/tests/ui/error-codes/E0771.stderr b/tests/ui/error-codes/E0771.stderr index dfeaa347941cb..93782079d06fd 100644 --- a/tests/ui/error-codes/E0771.stderr +++ b/tests/ui/error-codes/E0771.stderr @@ -1,18 +1,9 @@ error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/E0771.rs:4:41 + --> $DIR/E0771.rs:3:41 | LL | fn function_with_str<'a, const STRING: &'a str>() {} | ^^ the type must not depend on the parameter `'a` -warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/E0771.rs:1:30 - | -LL | #![feature(adt_const_params, unsized_const_params)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #95174 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/feature-gates/feature-gate-effective-target-features.default.stderr b/tests/ui/feature-gates/feature-gate-effective-target-features.default.stderr index 34a56fe342e21..e699c5d77b42c 100644 --- a/tests/ui/feature-gates/feature-gate-effective-target-features.default.stderr +++ b/tests/ui/feature-gates/feature-gate-effective-target-features.default.stderr @@ -1,5 +1,5 @@ error[E0658]: the `#[force_target_feature]` attribute is an experimental feature - --> $DIR/feature-gate-effective-target-features.rs:13:5 + --> $DIR/feature-gate-effective-target-features.rs:14:5 | LL | #[unsafe(force_target_feature(enable = "avx2"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | #[unsafe(force_target_feature(enable = "avx2"))] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: `#[target_feature(..)]` cannot be applied to safe trait method - --> $DIR/feature-gate-effective-target-features.rs:21:5 + --> $DIR/feature-gate-effective-target-features.rs:22:5 | LL | #[target_feature(enable = "avx2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method @@ -18,13 +18,13 @@ LL | fn foo(&self) {} | ------------- not an `unsafe` function error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/feature-gate-effective-target-features.rs:23:5 + --> $DIR/feature-gate-effective-target-features.rs:24:5 | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ expected safe fn, found unsafe fn | note: type in trait - --> $DIR/feature-gate-effective-target-features.rs:7:5 + --> $DIR/feature-gate-effective-target-features.rs:8:5 | LL | fn foo(&self); | ^^^^^^^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-effective-target-features.feature.stderr b/tests/ui/feature-gates/feature-gate-effective-target-features.feature.stderr index d51956fa4d2b5..bf9f5d73e0573 100644 --- a/tests/ui/feature-gates/feature-gate-effective-target-features.feature.stderr +++ b/tests/ui/feature-gates/feature-gate-effective-target-features.feature.stderr @@ -1,14 +1,18 @@ warning: the feature `effective_target_features` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/feature-gate-effective-target-features.rs:3:30 + --> $DIR/feature-gate-effective-target-features.rs:4:30 | LL | #![cfg_attr(feature, feature(effective_target_features))] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #143352 for more information - = note: `#[warn(incomplete_features)]` on by default +note: the lint level is defined here + --> $DIR/feature-gate-effective-target-features.rs:3:9 + | +LL | #![warn(incomplete_features)] + | ^^^^^^^^^^^^^^^^^^^ error: `#[target_feature(..)]` cannot be applied to safe trait method - --> $DIR/feature-gate-effective-target-features.rs:21:5 + --> $DIR/feature-gate-effective-target-features.rs:22:5 | LL | #[target_feature(enable = "avx2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method @@ -17,13 +21,13 @@ LL | fn foo(&self) {} | ------------- not an `unsafe` function error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/feature-gate-effective-target-features.rs:23:5 + --> $DIR/feature-gate-effective-target-features.rs:24:5 | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ expected safe fn, found unsafe fn | note: type in trait - --> $DIR/feature-gate-effective-target-features.rs:7:5 + --> $DIR/feature-gate-effective-target-features.rs:8:5 | LL | fn foo(&self); | ^^^^^^^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-effective-target-features.rs b/tests/ui/feature-gates/feature-gate-effective-target-features.rs index d383897e4382b..a8be61167aa2f 100644 --- a/tests/ui/feature-gates/feature-gate-effective-target-features.rs +++ b/tests/ui/feature-gates/feature-gate-effective-target-features.rs @@ -1,5 +1,6 @@ //@ revisions: default feature //@ only-x86_64 +#![warn(incomplete_features)] #![cfg_attr(feature, feature(effective_target_features))] //[feature]~^ WARN the feature `effective_target_features` is incomplete and may not be safe to use and/or cause compiler crashes diff --git a/tests/ui/feature-gates/feature-gate-unsafe_fields.rs b/tests/ui/feature-gates/feature-gate-unsafe_fields.rs index 2b0bbaa083570..27e8b5126f805 100644 --- a/tests/ui/feature-gates/feature-gate-unsafe_fields.rs +++ b/tests/ui/feature-gates/feature-gate-unsafe_fields.rs @@ -1,7 +1,7 @@ //@ compile-flags: --crate-type=lib //@ revisions: with_gate without_gate //@ [with_gate] check-pass - +#![warn(incomplete_features)] #![cfg_attr(with_gate, feature(unsafe_fields))] //[with_gate]~ WARNING #[cfg(false)] diff --git a/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr b/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr index a7deeb057d86a..4220930d46685 100644 --- a/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr +++ b/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr @@ -5,7 +5,11 @@ LL | #![cfg_attr(with_gate, feature(unsafe_fields))] | ^^^^^^^^^^^^^ | = note: see issue #132922 for more information - = note: `#[warn(incomplete_features)]` on by default +note: the lint level is defined here + --> $DIR/feature-gate-unsafe_fields.rs:4:9 + | +LL | #![warn(incomplete_features)] + | ^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted diff --git a/tests/ui/generic-associated-types/issue-87429-specialization.rs b/tests/ui/generic-associated-types/issue-87429-specialization.rs index 87e91162a8630..4a1e6aa6b332d 100644 --- a/tests/ui/generic-associated-types/issue-87429-specialization.rs +++ b/tests/ui/generic-associated-types/issue-87429-specialization.rs @@ -1,7 +1,6 @@ //@ check-fail #![feature(specialization)] -//~^ WARN incomplete trait Family { type Member<'a>: for<'b> PartialEq>; diff --git a/tests/ui/generic-associated-types/issue-87429-specialization.stderr b/tests/ui/generic-associated-types/issue-87429-specialization.stderr index 44f871e71c57d..dbe97bdb74318 100644 --- a/tests/ui/generic-associated-types/issue-87429-specialization.stderr +++ b/tests/ui/generic-associated-types/issue-87429-specialization.stderr @@ -1,22 +1,12 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-87429-specialization.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: can't compare `Foo` with `Foo` - --> $DIR/issue-87429-specialization.rs:20:31 + --> $DIR/issue-87429-specialization.rs:19:31 | LL | default type Member<'a> = Foo; | ^^^ no implementation for `Foo == Foo` | = help: the trait `PartialEq` is not implemented for `Foo` note: required by a bound in `Family::Member` - --> $DIR/issue-87429-specialization.rs:7:22 + --> $DIR/issue-87429-specialization.rs:6:22 | LL | type Member<'a>: for<'b> PartialEq>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Family::Member` @@ -26,6 +16,6 @@ LL + #[derive(PartialEq)] LL | struct Foo; | -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs index d6490d5b4f978..dc47eba2b3c63 100644 --- a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs +++ b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs @@ -1,5 +1,6 @@ //@ compile-flags: --crate-type=lib //@ revisions: with_gate without_gate +#![warn(incomplete_features)] #![cfg_attr(with_gate, feature(impl_restriction))] //[with_gate]~^ WARN the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes #![feature(auto_traits, const_trait_impl)] diff --git a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr index ad183b23e0138..834cc99f07553 100644 --- a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr +++ b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr @@ -1,5 +1,5 @@ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:8:14 + --> $DIR/recover-incorrect-impl-restriction.rs:9:14 | LL | pub impl(crate::foo) trait Baz {} | ^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | pub impl(in crate::foo) trait Baz {} | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:10:21 + --> $DIR/recover-incorrect-impl-restriction.rs:11:21 | LL | pub unsafe impl(crate::foo) trait BazUnsafe {} | ^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | pub unsafe impl(in crate::foo) trait BazUnsafe {} | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:12:19 + --> $DIR/recover-incorrect-impl-restriction.rs:13:19 | LL | pub auto impl(crate::foo) trait BazAuto {} | ^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | pub auto impl(in crate::foo) trait BazAuto {} | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:14:20 + --> $DIR/recover-incorrect-impl-restriction.rs:15:20 | LL | pub const impl(crate::foo) trait BazConst {} | ^^^^^^^^^^ @@ -63,7 +63,7 @@ LL | pub const impl(in crate::foo) trait BazConst {} | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:16:27 + --> $DIR/recover-incorrect-impl-restriction.rs:17:27 | LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} | ^^^^^^^^^^ @@ -79,7 +79,7 @@ LL | pub const unsafe impl(in crate::foo) trait BazConstUnsafe {} | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:18:26 + --> $DIR/recover-incorrect-impl-restriction.rs:19:26 | LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} | ^^^^^^^^^^ @@ -95,13 +95,17 @@ LL | pub unsafe auto impl(in crate::foo) trait BazUnsafeAuto {} | ++ warning: the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/recover-incorrect-impl-restriction.rs:3:32 + --> $DIR/recover-incorrect-impl-restriction.rs:4:32 | LL | #![cfg_attr(with_gate, feature(impl_restriction))] | ^^^^^^^^^^^^^^^^ | = note: see issue #105077 for more information - = note: `#[warn(incomplete_features)]` on by default +note: the lint level is defined here + --> $DIR/recover-incorrect-impl-restriction.rs:3:9 + | +LL | #![warn(incomplete_features)] + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors; 1 warning emitted diff --git a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr index d949172ffb458..223a7cd47cfb4 100644 --- a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr +++ b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr @@ -1,5 +1,5 @@ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:8:14 + --> $DIR/recover-incorrect-impl-restriction.rs:9:14 | LL | pub impl(crate::foo) trait Baz {} | ^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | pub impl(in crate::foo) trait Baz {} | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:10:21 + --> $DIR/recover-incorrect-impl-restriction.rs:11:21 | LL | pub unsafe impl(crate::foo) trait BazUnsafe {} | ^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | pub unsafe impl(in crate::foo) trait BazUnsafe {} | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:12:19 + --> $DIR/recover-incorrect-impl-restriction.rs:13:19 | LL | pub auto impl(crate::foo) trait BazAuto {} | ^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | pub auto impl(in crate::foo) trait BazAuto {} | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:14:20 + --> $DIR/recover-incorrect-impl-restriction.rs:15:20 | LL | pub const impl(crate::foo) trait BazConst {} | ^^^^^^^^^^ @@ -63,7 +63,7 @@ LL | pub const impl(in crate::foo) trait BazConst {} | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:16:27 + --> $DIR/recover-incorrect-impl-restriction.rs:17:27 | LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} | ^^^^^^^^^^ @@ -79,7 +79,7 @@ LL | pub const unsafe impl(in crate::foo) trait BazConstUnsafe {} | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:18:26 + --> $DIR/recover-incorrect-impl-restriction.rs:19:26 | LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} | ^^^^^^^^^^ @@ -95,7 +95,7 @@ LL | pub unsafe auto impl(in crate::foo) trait BazUnsafeAuto {} | ++ error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:8:9 + --> $DIR/recover-incorrect-impl-restriction.rs:9:9 | LL | pub impl(crate::foo) trait Baz {} | ^^^^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | pub impl(crate::foo) trait Baz {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:10:16 + --> $DIR/recover-incorrect-impl-restriction.rs:11:16 | LL | pub unsafe impl(crate::foo) trait BazUnsafe {} | ^^^^^^^^^^^^^^^^ @@ -115,7 +115,7 @@ LL | pub unsafe impl(crate::foo) trait BazUnsafe {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:12:14 + --> $DIR/recover-incorrect-impl-restriction.rs:13:14 | LL | pub auto impl(crate::foo) trait BazAuto {} | ^^^^^^^^^^^^^^^^ @@ -125,7 +125,7 @@ LL | pub auto impl(crate::foo) trait BazAuto {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:14:15 + --> $DIR/recover-incorrect-impl-restriction.rs:15:15 | LL | pub const impl(crate::foo) trait BazConst {} | ^^^^^^^^^^^^^^^^ @@ -135,7 +135,7 @@ LL | pub const impl(crate::foo) trait BazConst {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:16:22 + --> $DIR/recover-incorrect-impl-restriction.rs:17:22 | LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} | ^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:18:21 + --> $DIR/recover-incorrect-impl-restriction.rs:19:21 | LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs index 62622e1d55861..ce36a49b145b0 100644 --- a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs +++ b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs @@ -1,5 +1,6 @@ //@ compile-flags: --crate-type=lib //@ revisions: with_gate without_gate +#![warn(incomplete_features)] #![cfg_attr(with_gate, feature(impl_restriction))] //[with_gate]~^ WARN the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes #![feature(auto_traits, const_trait_impl, trait_alias)] diff --git a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr index 70287aca42aad..7be030052df50 100644 --- a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr +++ b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr @@ -1,83 +1,87 @@ error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:7:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:8:1 | LL | impl(crate) trait Alias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `auto` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:10:1 | LL | auto impl(in crate) trait AutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:10:1 | LL | auto impl(in crate) trait AutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:1 | LL | unsafe impl(self) trait UnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:1 | LL | unsafe impl(self) trait UnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:15:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:16:1 | LL | const impl(in self) trait ConstAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:19:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:20:5 | LL | impl(super) trait InnerAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:22:5 | LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:22:5 | LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `auto` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 | LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 | LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 | LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted warning: the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:3:32 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:4:32 | LL | #![cfg_attr(with_gate, feature(impl_restriction))] | ^^^^^^^^^^^^^^^^ | = note: see issue #105077 for more information - = note: `#[warn(incomplete_features)]` on by default +note: the lint level is defined here + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:3:9 + | +LL | #![warn(incomplete_features)] + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to 12 previous errors; 1 warning emitted diff --git a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr index 7bff90396708d..c99bfce5da2c5 100644 --- a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr +++ b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr @@ -1,77 +1,77 @@ error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:7:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:8:1 | LL | impl(crate) trait Alias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `auto` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:10:1 | LL | auto impl(in crate) trait AutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:10:1 | LL | auto impl(in crate) trait AutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:1 | LL | unsafe impl(self) trait UnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:1 | LL | unsafe impl(self) trait UnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:15:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:16:1 | LL | const impl(in self) trait ConstAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:19:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:20:5 | LL | impl(super) trait InnerAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:22:5 | LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:22:5 | LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `auto` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 | LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 | LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 | LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:7:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:8:1 | LL | impl(crate) trait Alias = Copy; | ^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | impl(crate) trait Alias = Copy; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:6 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:10:6 | LL | auto impl(in crate) trait AutoAlias = Copy; | ^^^^^^^^^^^^^^ @@ -91,7 +91,7 @@ LL | auto impl(in crate) trait AutoAlias = Copy; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:8 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:8 | LL | unsafe impl(self) trait UnsafeAlias = Copy; | ^^^^^^^^^^ @@ -101,7 +101,7 @@ LL | unsafe impl(self) trait UnsafeAlias = Copy; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:15:7 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:16:7 | LL | const impl(in self) trait ConstAlias = Copy; | ^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | const impl(in self) trait ConstAlias = Copy; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:19:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:20:5 | LL | impl(super) trait InnerAlias = Copy; | ^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | impl(super) trait InnerAlias = Copy; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:18 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:22:18 | LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^ @@ -131,7 +131,7 @@ LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:17 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:17 | LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/equality-rpass.rs b/tests/ui/impl-trait/equality-rpass.rs index da750f4ef1ba3..d5cac80a08d7b 100644 --- a/tests/ui/impl-trait/equality-rpass.rs +++ b/tests/ui/impl-trait/equality-rpass.rs @@ -1,6 +1,6 @@ //@ run-pass -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Foo: std::fmt::Debug + Eq {} diff --git a/tests/ui/impl-trait/equality-rpass.stderr b/tests/ui/impl-trait/equality-rpass.stderr deleted file mode 100644 index bde8362fdf81e..0000000000000 --- a/tests/ui/impl-trait/equality-rpass.stderr +++ /dev/null @@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/equality-rpass.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/impl-trait/equality.rs b/tests/ui/impl-trait/equality.rs index 07fc4a5d41ace..4a315639bde9a 100644 --- a/tests/ui/impl-trait/equality.rs +++ b/tests/ui/impl-trait/equality.rs @@ -1,6 +1,6 @@ //@ dont-require-annotations: NOTE -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Foo: Copy + ToString {} diff --git a/tests/ui/impl-trait/equality.stderr b/tests/ui/impl-trait/equality.stderr index 7f965b9609a9d..3c765da66bdcf 100644 --- a/tests/ui/impl-trait/equality.stderr +++ b/tests/ui/impl-trait/equality.stderr @@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/equality.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types --> $DIR/equality.rs:17:5 | @@ -48,7 +38,7 @@ help: the following other types implement trait `Add` = note: `&u32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/equality2.rs b/tests/ui/impl-trait/equality2.rs index 808c600ecb7b7..44d356e0e262e 100644 --- a/tests/ui/impl-trait/equality2.rs +++ b/tests/ui/impl-trait/equality2.rs @@ -1,6 +1,6 @@ //@ dont-require-annotations: NOTE -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] trait Foo: Copy + ToString {} diff --git a/tests/ui/impl-trait/equality2.stderr b/tests/ui/impl-trait/equality2.stderr index 2fa7eb288ff87..ce0ccea20afb7 100644 --- a/tests/ui/impl-trait/equality2.stderr +++ b/tests/ui/impl-trait/equality2.stderr @@ -1,13 +1,3 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/equality2.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types --> $DIR/equality2.rs:27:18 | @@ -72,6 +62,6 @@ LL | x.0); found opaque type `impl Foo` (`u32`) = note: distinct uses of `impl Trait` result in different opaque types -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs index 351cdad4ee115..ba6dfd4dfa8f6 100644 --- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs +++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs @@ -1,7 +1,6 @@ //@ compile-flags: -Znext-solver #![feature(lazy_type_alias)] -//~^ WARN the feature `lazy_type_alias` is incomplete trait Foo {} diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr index a95670ced8678..03c5d7a567690 100644 --- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr +++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr @@ -1,53 +1,44 @@ -warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/alias-bounds-when-not-wf.rs:3:12 - | -LL | #![feature(lazy_type_alias)] - | ^^^^^^^^^^^^^^^ - | - = note: see issue #112792 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `usize: Foo` is not satisfied - --> $DIR/alias-bounds-when-not-wf.rs:16:15 + --> $DIR/alias-bounds-when-not-wf.rs:15:15 | LL | fn hello(_: W>) {} | ^^^^^^^^ the trait `Foo` is not implemented for `usize` | help: this trait has no implementations, consider adding one - --> $DIR/alias-bounds-when-not-wf.rs:6:1 + --> $DIR/alias-bounds-when-not-wf.rs:5:1 | LL | trait Foo {} | ^^^^^^^^^ note: required by a bound in `A` - --> $DIR/alias-bounds-when-not-wf.rs:8:11 + --> $DIR/alias-bounds-when-not-wf.rs:7:11 | LL | type A = T; | ^^^ required by this bound in `A` error[E0277]: the trait bound `usize: Foo` is not satisfied - --> $DIR/alias-bounds-when-not-wf.rs:16:10 + --> $DIR/alias-bounds-when-not-wf.rs:15:10 | LL | fn hello(_: W>) {} | ^ the trait `Foo` is not implemented for `usize` | help: this trait has no implementations, consider adding one - --> $DIR/alias-bounds-when-not-wf.rs:6:1 + --> $DIR/alias-bounds-when-not-wf.rs:5:1 | LL | trait Foo {} | ^^^^^^^^^ error[E0277]: the trait bound `usize: Foo` is not satisfied - --> $DIR/alias-bounds-when-not-wf.rs:16:1 + --> $DIR/alias-bounds-when-not-wf.rs:15:1 | LL | fn hello(_: W>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `usize` | help: this trait has no implementations, consider adding one - --> $DIR/alias-bounds-when-not-wf.rs:6:1 + --> $DIR/alias-bounds-when-not-wf.rs:5:1 | LL | trait Foo {} | ^^^^^^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/layout/gce-rigid-const-in-array-len.rs b/tests/ui/layout/gce-rigid-const-in-array-len.rs index 8e57907a2c5ec..d8cc415ba1c24 100644 --- a/tests/ui/layout/gce-rigid-const-in-array-len.rs +++ b/tests/ui/layout/gce-rigid-const-in-array-len.rs @@ -12,7 +12,7 @@ //! constant. #![feature(rustc_attrs)] -#![feature(generic_const_exprs)] //~ WARNING: the feature `generic_const_exprs` is incomplete +#![feature(generic_const_exprs)] #![feature(trivial_bounds)] #![crate_type = "lib"] diff --git a/tests/ui/layout/gce-rigid-const-in-array-len.stderr b/tests/ui/layout/gce-rigid-const-in-array-len.stderr index 6149debdfe88d..9038563159789 100644 --- a/tests/ui/layout/gce-rigid-const-in-array-len.stderr +++ b/tests/ui/layout/gce-rigid-const-in-array-len.stderr @@ -1,17 +1,8 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/gce-rigid-const-in-array-len.rs:15:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 for more information - = note: `#[warn(incomplete_features)]` on by default - error: the type `[u8; ::B]` has an unknown layout --> $DIR/gce-rigid-const-in-array-len.rs:25:1 | LL | struct S([u8; ::B]) | ^^^^^^^^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error diff --git a/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs b/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs index 6ded9118700c0..e9e7de84a7a46 100644 --- a/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs +++ b/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs @@ -1,7 +1,6 @@ // regression test for #127351 #![feature(lazy_type_alias)] -//~^ WARN the feature `lazy_type_alias` is incomplete type ExplicitTypeOutlives = T; diff --git a/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr b/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr index 3a5ded60241b1..7aa34a22f736e 100644 --- a/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr +++ b/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr @@ -1,20 +1,11 @@ -warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad-lazy-type-alias.rs:3:12 - | -LL | #![feature(lazy_type_alias)] - | ^^^^^^^^^^^^^^^ - | - = note: see issue #112792 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0107]: missing generics for type alias `ExplicitTypeOutlives` - --> $DIR/bad-lazy-type-alias.rs:9:24 + --> $DIR/bad-lazy-type-alias.rs:8:24 | LL | _significant_drop: ExplicitTypeOutlives, | ^^^^^^^^^^^^^^^^^^^^ expected 1 generic argument | note: type alias defined here, with 1 generic parameter: `T` - --> $DIR/bad-lazy-type-alias.rs:6:6 + --> $DIR/bad-lazy-type-alias.rs:5:6 | LL | type ExplicitTypeOutlives = T; | ^^^^^^^^^^^^^^^^^^^^ - @@ -23,6 +14,6 @@ help: add missing generic argument LL | _significant_drop: ExplicitTypeOutlives, | +++ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/lazy-type-alias/coerce-behind-lazy.current.stderr b/tests/ui/lazy-type-alias/coerce-behind-lazy.current.stderr deleted file mode 100644 index 78dd05b78af1d..0000000000000 --- a/tests/ui/lazy-type-alias/coerce-behind-lazy.current.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/coerce-behind-lazy.rs:6:12 - | -LL | #![feature(lazy_type_alias)] - | ^^^^^^^^^^^^^^^ - | - = note: see issue #112792 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/lazy-type-alias/coerce-behind-lazy.next.stderr b/tests/ui/lazy-type-alias/coerce-behind-lazy.next.stderr deleted file mode 100644 index 78dd05b78af1d..0000000000000 --- a/tests/ui/lazy-type-alias/coerce-behind-lazy.next.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/coerce-behind-lazy.rs:6:12 - | -LL | #![feature(lazy_type_alias)] - | ^^^^^^^^^^^^^^^ - | - = note: see issue #112792 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/lazy-type-alias/coerce-behind-lazy.rs b/tests/ui/lazy-type-alias/coerce-behind-lazy.rs index 7873ff46b66fb..a69e39b02b32f 100644 --- a/tests/ui/lazy-type-alias/coerce-behind-lazy.rs +++ b/tests/ui/lazy-type-alias/coerce-behind-lazy.rs @@ -4,7 +4,6 @@ //@[next] compile-flags: -Znext-solver #![feature(lazy_type_alias)] -//~^ WARN the feature `lazy_type_alias` is incomplete use std::any::Any; diff --git a/tests/ui/lazy-type-alias/enum-variant.rs b/tests/ui/lazy-type-alias/enum-variant.rs index d9b7dff266473..236e1933a8a93 100644 --- a/tests/ui/lazy-type-alias/enum-variant.rs +++ b/tests/ui/lazy-type-alias/enum-variant.rs @@ -2,7 +2,6 @@ //@ check-pass #![feature(lazy_type_alias)] -//~^ WARN the feature `lazy_type_alias` is incomplete and may not be safe to use enum Enum { Unit, diff --git a/tests/ui/lazy-type-alias/enum-variant.stderr b/tests/ui/lazy-type-alias/enum-variant.stderr deleted file mode 100644 index 4360db917783f..0000000000000 --- a/tests/ui/lazy-type-alias/enum-variant.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/enum-variant.rs:4:12 - | -LL | #![feature(lazy_type_alias)] - | ^^^^^^^^^^^^^^^ - | - = note: see issue #112792 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.rs b/tests/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.rs index a9f0cdae1f6c1..cd2eaa5337e8c 100644 --- a/tests/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.rs +++ b/tests/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.rs @@ -1,7 +1,7 @@ //@ run-pass #![feature(marker_trait_attr)] -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] #[marker] trait MyMarker {} diff --git a/tests/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr b/tests/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr deleted file mode 100644 index 649e58915d0a2..0000000000000 --- a/tests/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr +++ /dev/null @@ -1,12 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/overlap-doesnt-conflict-with-specialization.rs:4:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/parser/assoc/assoc-static-semantic-fail.rs b/tests/ui/parser/assoc/assoc-static-semantic-fail.rs index 403160f1253a4..de0cee6ff9966 100644 --- a/tests/ui/parser/assoc/assoc-static-semantic-fail.rs +++ b/tests/ui/parser/assoc/assoc-static-semantic-fail.rs @@ -1,7 +1,6 @@ // Semantically, we do not allow e.g., `static X: u8 = 0;` as an associated item. #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete fn main() {} diff --git a/tests/ui/parser/assoc/assoc-static-semantic-fail.stderr b/tests/ui/parser/assoc/assoc-static-semantic-fail.stderr index cc21df77353f5..4ac3528a6d42f 100644 --- a/tests/ui/parser/assoc/assoc-static-semantic-fail.stderr +++ b/tests/ui/parser/assoc/assoc-static-semantic-fail.stderr @@ -1,17 +1,17 @@ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:10:5 + --> $DIR/assoc-static-semantic-fail.rs:9:5 | LL | static IA: u8 = 0; | ^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:12:5 + --> $DIR/assoc-static-semantic-fail.rs:11:5 | LL | static IB: u8; | ^^^^^^^^^^^^^^ error: a static item cannot be `default` - --> $DIR/assoc-static-semantic-fail.rs:15:5 + --> $DIR/assoc-static-semantic-fail.rs:14:5 | LL | default static IC: u8 = 0; | ^^^^^^^ `default` because of this @@ -19,13 +19,13 @@ LL | default static IC: u8 = 0; = note: only associated `fn`, `const`, and `type` items can be `default` error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:15:5 + --> $DIR/assoc-static-semantic-fail.rs:14:5 | LL | default static IC: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a static item cannot be `default` - --> $DIR/assoc-static-semantic-fail.rs:18:16 + --> $DIR/assoc-static-semantic-fail.rs:17:16 | LL | pub(crate) default static ID: u8; | ^^^^^^^ `default` because of this @@ -33,25 +33,25 @@ LL | pub(crate) default static ID: u8; = note: only associated `fn`, `const`, and `type` items can be `default` error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:18:5 + --> $DIR/assoc-static-semantic-fail.rs:17:5 | LL | pub(crate) default static ID: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:25:5 + --> $DIR/assoc-static-semantic-fail.rs:24:5 | LL | static TA: u8 = 0; | ^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:27:5 + --> $DIR/assoc-static-semantic-fail.rs:26:5 | LL | static TB: u8; | ^^^^^^^^^^^^^^ error: a static item cannot be `default` - --> $DIR/assoc-static-semantic-fail.rs:29:5 + --> $DIR/assoc-static-semantic-fail.rs:28:5 | LL | default static TC: u8 = 0; | ^^^^^^^ `default` because of this @@ -59,13 +59,13 @@ LL | default static TC: u8 = 0; = note: only associated `fn`, `const`, and `type` items can be `default` error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:29:5 + --> $DIR/assoc-static-semantic-fail.rs:28:5 | LL | default static TC: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a static item cannot be `default` - --> $DIR/assoc-static-semantic-fail.rs:32:16 + --> $DIR/assoc-static-semantic-fail.rs:31:16 | LL | pub(crate) default static TD: u8; | ^^^^^^^ `default` because of this @@ -73,25 +73,25 @@ LL | pub(crate) default static TD: u8; = note: only associated `fn`, `const`, and `type` items can be `default` error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:32:5 + --> $DIR/assoc-static-semantic-fail.rs:31:5 | LL | pub(crate) default static TD: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:39:5 + --> $DIR/assoc-static-semantic-fail.rs:38:5 | LL | static TA: u8 = 0; | ^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:41:5 + --> $DIR/assoc-static-semantic-fail.rs:40:5 | LL | static TB: u8; | ^^^^^^^^^^^^^^ error: a static item cannot be `default` - --> $DIR/assoc-static-semantic-fail.rs:44:5 + --> $DIR/assoc-static-semantic-fail.rs:43:5 | LL | default static TC: u8 = 0; | ^^^^^^^ `default` because of this @@ -99,13 +99,13 @@ LL | default static TC: u8 = 0; = note: only associated `fn`, `const`, and `type` items can be `default` error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:44:5 + --> $DIR/assoc-static-semantic-fail.rs:43:5 | LL | default static TC: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a static item cannot be `default` - --> $DIR/assoc-static-semantic-fail.rs:47:9 + --> $DIR/assoc-static-semantic-fail.rs:46:9 | LL | pub default static TD: u8; | ^^^^^^^ `default` because of this @@ -113,13 +113,13 @@ LL | pub default static TD: u8; = note: only associated `fn`, `const`, and `type` items can be `default` error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:47:5 + --> $DIR/assoc-static-semantic-fail.rs:46:5 | LL | pub default static TD: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: associated constant in `impl` without body - --> $DIR/assoc-static-semantic-fail.rs:12:5 + --> $DIR/assoc-static-semantic-fail.rs:11:5 | LL | static IB: u8; | ^^^^^^^^^^^^^- @@ -127,7 +127,7 @@ LL | static IB: u8; | help: provide a definition for the constant: `= ;` error: associated constant in `impl` without body - --> $DIR/assoc-static-semantic-fail.rs:18:5 + --> $DIR/assoc-static-semantic-fail.rs:17:5 | LL | pub(crate) default static ID: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -135,7 +135,7 @@ LL | pub(crate) default static ID: u8; | help: provide a definition for the constant: `= ;` error[E0449]: visibility qualifiers are not permitted here - --> $DIR/assoc-static-semantic-fail.rs:32:5 + --> $DIR/assoc-static-semantic-fail.rs:31:5 | LL | pub(crate) default static TD: u8; | ^^^^^^^^^^ help: remove the qualifier @@ -143,7 +143,7 @@ LL | pub(crate) default static TD: u8; = note: trait items always share the visibility of their trait error: associated constant in `impl` without body - --> $DIR/assoc-static-semantic-fail.rs:41:5 + --> $DIR/assoc-static-semantic-fail.rs:40:5 | LL | static TB: u8; | ^^^^^^^^^^^^^- @@ -151,7 +151,7 @@ LL | static TB: u8; | help: provide a definition for the constant: `= ;` error: associated constant in `impl` without body - --> $DIR/assoc-static-semantic-fail.rs:47:5 + --> $DIR/assoc-static-semantic-fail.rs:46:5 | LL | pub default static TD: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -159,23 +159,13 @@ LL | pub default static TD: u8; | help: provide a definition for the constant: `= ;` error[E0449]: visibility qualifiers are not permitted here - --> $DIR/assoc-static-semantic-fail.rs:47:5 + --> $DIR/assoc-static-semantic-fail.rs:46:5 | LL | pub default static TD: u8; | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/assoc-static-semantic-fail.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 24 previous errors; 1 warning emitted +error: aborting due to 24 previous errors For more information about this error, try `rustc --explain E0449`. diff --git a/tests/ui/parser/default.rs b/tests/ui/parser/default.rs index d1058ceb2a1c4..81821ce238774 100644 --- a/tests/ui/parser/default.rs +++ b/tests/ui/parser/default.rs @@ -1,7 +1,6 @@ // Test successful and unsuccessful parsing of the `default` contextual keyword #![feature(specialization)] -//~^ WARN the feature `specialization` is incomplete trait Foo { fn foo() -> T; diff --git a/tests/ui/parser/default.stderr b/tests/ui/parser/default.stderr index c420e5a774d20..1f2312d0c6e8f 100644 --- a/tests/ui/parser/default.stderr +++ b/tests/ui/parser/default.stderr @@ -1,5 +1,5 @@ error: `default` is not followed by an item - --> $DIR/default.rs:23:5 + --> $DIR/default.rs:22:5 | LL | default pub fn foo() -> T { T::default() } | ^^^^^^^ the `default` qualifier @@ -7,7 +7,7 @@ LL | default pub fn foo() -> T { T::default() } = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` error: non-item in item list - --> $DIR/default.rs:23:13 + --> $DIR/default.rs:22:13 | LL | impl Foo for u32 { | - item list starts here @@ -18,25 +18,15 @@ LL | } | - item list ends here error[E0449]: visibility qualifiers are not permitted here - --> $DIR/default.rs:17:5 + --> $DIR/default.rs:16:5 | LL | pub default fn foo() -> T { | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default.rs:3:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - error[E0046]: not all trait items implemented, missing: `foo` - --> $DIR/default.rs:22:1 + --> $DIR/default.rs:21:1 | LL | fn foo() -> T; | -------------------------- `foo` from trait @@ -44,7 +34,7 @@ LL | fn foo() -> T; LL | impl Foo for u32 { | ^^^^^^^^^^^^^^^^ missing `foo` in implementation -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 4 previous errors Some errors have detailed explanations: E0046, E0449. For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/parser/defaultness-invalid-places-fail-semantic.rs b/tests/ui/parser/defaultness-invalid-places-fail-semantic.rs index bff53f66e19d8..f274040083134 100644 --- a/tests/ui/parser/defaultness-invalid-places-fail-semantic.rs +++ b/tests/ui/parser/defaultness-invalid-places-fail-semantic.rs @@ -1,4 +1,4 @@ -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] fn main() {} diff --git a/tests/ui/parser/defaultness-invalid-places-fail-semantic.stderr b/tests/ui/parser/defaultness-invalid-places-fail-semantic.stderr index 41fad3a5de34d..4adb0ab25c6f1 100644 --- a/tests/ui/parser/defaultness-invalid-places-fail-semantic.stderr +++ b/tests/ui/parser/defaultness-invalid-places-fail-semantic.stderr @@ -70,15 +70,5 @@ LL | default fn h() {} | | | `default` because of this -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/defaultness-invalid-places-fail-semantic.rs:1:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 9 previous errors; 1 warning emitted +error: aborting due to 9 previous errors diff --git a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr index d26ba93e72117..75a633cd49a3d 100644 --- a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr +++ b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr @@ -1,5 +1,5 @@ error: unreachable pattern - --> $DIR/empty-types.rs:48:9 + --> $DIR/empty-types.rs:47:9 | LL | _ => {} | ^------ @@ -9,13 +9,13 @@ LL | _ => {} | = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types note: the lint level is defined here - --> $DIR/empty-types.rs:14:9 + --> $DIR/empty-types.rs:13:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/empty-types.rs:51:9 + --> $DIR/empty-types.rs:50:9 | LL | _x => {} | ^^------ @@ -26,7 +26,7 @@ LL | _x => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: type `&!` is non-empty - --> $DIR/empty-types.rs:55:11 + --> $DIR/empty-types.rs:54:11 | LL | match ref_never {} | ^^^^^^^^^ @@ -41,7 +41,7 @@ LL ~ } | error: unreachable pattern - --> $DIR/empty-types.rs:69:9 + --> $DIR/empty-types.rs:68:9 | LL | (_, _) => {} | ^^^^^^------ @@ -52,7 +52,7 @@ LL | (_, _) => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:75:9 + --> $DIR/empty-types.rs:74:9 | LL | _ => {} | ^------ @@ -63,7 +63,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:78:9 + --> $DIR/empty-types.rs:77:9 | LL | (_, _) => {} | ^^^^^^------ @@ -74,7 +74,7 @@ LL | (_, _) => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:82:9 + --> $DIR/empty-types.rs:81:9 | LL | _ => {} | ^------ @@ -85,7 +85,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `Ok(_)` not covered - --> $DIR/empty-types.rs:86:11 + --> $DIR/empty-types.rs:85:11 | LL | match res_u32_never {} | ^^^^^^^^^^^^^ pattern `Ok(_)` not covered @@ -104,7 +104,7 @@ LL ~ } | error: unreachable pattern - --> $DIR/empty-types.rs:93:9 + --> $DIR/empty-types.rs:92:9 | LL | Err(_) => {} | ^^^^^^------ @@ -115,7 +115,7 @@ LL | Err(_) => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:98:9 + --> $DIR/empty-types.rs:97:9 | LL | Err(_) => {} | ^^^^^^------ @@ -126,7 +126,7 @@ LL | Err(_) => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered - --> $DIR/empty-types.rs:95:11 + --> $DIR/empty-types.rs:94:11 | LL | match res_u32_never { | ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered @@ -144,7 +144,7 @@ LL ~ Ok(1_u32..=u32::MAX) => todo!() | error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:101:9 + --> $DIR/empty-types.rs:100:9 | LL | let Ok(_x) = res_u32_never.as_ref(); | ^^^^^^ pattern `Err(_)` not covered @@ -158,7 +158,7 @@ LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() }; | ++++++++++++++++ error: unreachable pattern - --> $DIR/empty-types.rs:111:9 + --> $DIR/empty-types.rs:110:9 | LL | _ => {} | ^------ @@ -169,7 +169,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:114:9 + --> $DIR/empty-types.rs:113:9 | LL | Ok(_) => {} | ^^^^^------ @@ -180,7 +180,7 @@ LL | Ok(_) => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:117:9 + --> $DIR/empty-types.rs:116:9 | LL | Ok(_) => {} | ^^^^^------ @@ -191,7 +191,7 @@ LL | Ok(_) => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:118:9 + --> $DIR/empty-types.rs:117:9 | LL | _ => {} | ^------ @@ -202,7 +202,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:121:9 + --> $DIR/empty-types.rs:120:9 | LL | Ok(_) => {} | ^^^^^------ @@ -213,7 +213,7 @@ LL | Ok(_) => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:122:9 + --> $DIR/empty-types.rs:121:9 | LL | Err(_) => {} | ^^^^^^------ @@ -224,7 +224,7 @@ LL | Err(_) => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:131:13 + --> $DIR/empty-types.rs:130:13 | LL | _ => {} | ^------ @@ -235,7 +235,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:134:13 + --> $DIR/empty-types.rs:133:13 | LL | _ if false => {} | ^--------------- @@ -246,7 +246,7 @@ LL | _ if false => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:142:13 + --> $DIR/empty-types.rs:141:13 | LL | Some(_) => {} | ^^^^^^^------ @@ -257,7 +257,7 @@ LL | Some(_) => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:146:13 + --> $DIR/empty-types.rs:145:13 | LL | None => {} | ---- matches all the relevant values @@ -265,7 +265,7 @@ LL | _ => {} | ^ no value can reach this error: unreachable pattern - --> $DIR/empty-types.rs:198:13 + --> $DIR/empty-types.rs:197:13 | LL | _ => {} | ^------ @@ -276,7 +276,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:203:13 + --> $DIR/empty-types.rs:202:13 | LL | _ => {} | ^------ @@ -287,7 +287,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:208:13 + --> $DIR/empty-types.rs:207:13 | LL | _ => {} | ^------ @@ -298,7 +298,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:213:13 + --> $DIR/empty-types.rs:212:13 | LL | _ => {} | ^------ @@ -309,7 +309,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:219:13 + --> $DIR/empty-types.rs:218:13 | LL | _ => {} | ^------ @@ -320,7 +320,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:280:9 + --> $DIR/empty-types.rs:279:9 | LL | _ => {} | ^------ @@ -331,7 +331,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:283:9 + --> $DIR/empty-types.rs:282:9 | LL | (_, _) => {} | ^^^^^^------ @@ -342,7 +342,7 @@ LL | (_, _) => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:286:9 + --> $DIR/empty-types.rs:285:9 | LL | Ok(_) => {} | ^^^^^------ @@ -353,7 +353,7 @@ LL | Ok(_) => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:287:9 + --> $DIR/empty-types.rs:286:9 | LL | Err(_) => {} | ^^^^^^------ @@ -364,7 +364,7 @@ LL | Err(_) => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty - --> $DIR/empty-types.rs:326:11 + --> $DIR/empty-types.rs:325:11 | LL | match slice_never {} | ^^^^^^^^^^^ @@ -378,7 +378,7 @@ LL ~ } | error[E0004]: non-exhaustive patterns: `&[]` not covered - --> $DIR/empty-types.rs:337:11 + --> $DIR/empty-types.rs:336:11 | LL | match slice_never { | ^^^^^^^^^^^ pattern `&[]` not covered @@ -391,7 +391,7 @@ LL + &[] => todo!() | error[E0004]: non-exhaustive patterns: `&[]` not covered - --> $DIR/empty-types.rs:351:11 + --> $DIR/empty-types.rs:350:11 | LL | match slice_never { | ^^^^^^^^^^^ pattern `&[]` not covered @@ -405,7 +405,7 @@ LL + &[] => todo!() | error[E0004]: non-exhaustive patterns: type `[!]` is non-empty - --> $DIR/empty-types.rs:358:11 + --> $DIR/empty-types.rs:357:11 | LL | match *slice_never {} | ^^^^^^^^^^^^ @@ -419,7 +419,7 @@ LL ~ } | error: unreachable pattern - --> $DIR/empty-types.rs:367:9 + --> $DIR/empty-types.rs:366:9 | LL | _ => {} | ^------ @@ -430,7 +430,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:370:9 + --> $DIR/empty-types.rs:369:9 | LL | [_, _, _] => {} | ^^^^^^^^^------ @@ -441,7 +441,7 @@ LL | [_, _, _] => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:373:9 + --> $DIR/empty-types.rs:372:9 | LL | [_, ..] => {} | ^^^^^^^------ @@ -452,7 +452,7 @@ LL | [_, ..] => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty - --> $DIR/empty-types.rs:387:11 + --> $DIR/empty-types.rs:386:11 | LL | match array_0_never {} | ^^^^^^^^^^^^^ @@ -466,7 +466,7 @@ LL ~ } | error: unreachable pattern - --> $DIR/empty-types.rs:394:9 + --> $DIR/empty-types.rs:393:9 | LL | [] => {} | -- matches all the relevant values @@ -474,7 +474,7 @@ LL | _ => {} | ^ no value can reach this error[E0004]: non-exhaustive patterns: `[]` not covered - --> $DIR/empty-types.rs:396:11 + --> $DIR/empty-types.rs:395:11 | LL | match array_0_never { | ^^^^^^^^^^^^^ pattern `[]` not covered @@ -488,7 +488,7 @@ LL + [] => todo!() | error: unreachable pattern - --> $DIR/empty-types.rs:415:9 + --> $DIR/empty-types.rs:414:9 | LL | Some(_) => {} | ^^^^^^^------ @@ -499,7 +499,7 @@ LL | Some(_) => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:420:9 + --> $DIR/empty-types.rs:419:9 | LL | Some(_a) => {} | ^^^^^^^^------ @@ -510,7 +510,7 @@ LL | Some(_a) => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:425:9 + --> $DIR/empty-types.rs:424:9 | LL | None => {} | ---- matches all the relevant values @@ -519,7 +519,7 @@ LL | _ => {} | ^ no value can reach this error: unreachable pattern - --> $DIR/empty-types.rs:430:9 + --> $DIR/empty-types.rs:429:9 | LL | None => {} | ---- matches all the relevant values @@ -528,7 +528,7 @@ LL | _a => {} | ^^ no value can reach this error: unreachable pattern - --> $DIR/empty-types.rs:602:9 + --> $DIR/empty-types.rs:601:9 | LL | _ => {} | ^------ @@ -539,7 +539,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:605:9 + --> $DIR/empty-types.rs:604:9 | LL | _x => {} | ^^------ @@ -550,7 +550,7 @@ LL | _x => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:608:9 + --> $DIR/empty-types.rs:607:9 | LL | _ if false => {} | ^--------------- @@ -561,7 +561,7 @@ LL | _ if false => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:611:9 + --> $DIR/empty-types.rs:610:9 | LL | _x if false => {} | ^^--------------- diff --git a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr index 55d6eb82a3463..046c0d5f6588f 100644 --- a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr +++ b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr @@ -1,14 +1,5 @@ -warning: the feature `never_patterns` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/empty-types.rs:11:33 - | -LL | #![cfg_attr(never_pats, feature(never_patterns))] - | ^^^^^^^^^^^^^^ - | - = note: see issue #118155 for more information - = note: `#[warn(incomplete_features)]` on by default - error: unreachable pattern - --> $DIR/empty-types.rs:48:9 + --> $DIR/empty-types.rs:47:9 | LL | _ => {} | ^------ @@ -18,13 +9,13 @@ LL | _ => {} | = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types note: the lint level is defined here - --> $DIR/empty-types.rs:14:9 + --> $DIR/empty-types.rs:13:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/empty-types.rs:51:9 + --> $DIR/empty-types.rs:50:9 | LL | _x => {} | ^^------ @@ -35,7 +26,7 @@ LL | _x => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: type `&!` is non-empty - --> $DIR/empty-types.rs:55:11 + --> $DIR/empty-types.rs:54:11 | LL | match ref_never {} | ^^^^^^^^^ @@ -50,7 +41,7 @@ LL ~ } | error: unreachable pattern - --> $DIR/empty-types.rs:82:9 + --> $DIR/empty-types.rs:81:9 | LL | _ => {} | ^------ @@ -61,7 +52,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `Ok(_)` not covered - --> $DIR/empty-types.rs:86:11 + --> $DIR/empty-types.rs:85:11 | LL | match res_u32_never {} | ^^^^^^^^^^^^^ pattern `Ok(_)` not covered @@ -80,7 +71,7 @@ LL ~ } | error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered - --> $DIR/empty-types.rs:95:11 + --> $DIR/empty-types.rs:94:11 | LL | match res_u32_never { | ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered @@ -98,7 +89,7 @@ LL ~ Ok(1_u32..=u32::MAX) => todo!() | error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:101:9 + --> $DIR/empty-types.rs:100:9 | LL | let Ok(_x) = res_u32_never.as_ref(); | ^^^^^^ pattern `Err(_)` not covered @@ -112,7 +103,7 @@ LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() }; | ++++++++++++++++ error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:105:9 + --> $DIR/empty-types.rs:104:9 | LL | let Ok(_x) = &res_u32_never; | ^^^^^^ pattern `&Err(!)` not covered @@ -126,7 +117,7 @@ LL | let Ok(_x) = &res_u32_never else { todo!() }; | ++++++++++++++++ error: unreachable pattern - --> $DIR/empty-types.rs:131:13 + --> $DIR/empty-types.rs:130:13 | LL | _ => {} | ^------ @@ -137,7 +128,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:134:13 + --> $DIR/empty-types.rs:133:13 | LL | _ if false => {} | ^--------------- @@ -148,7 +139,7 @@ LL | _ if false => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `Some(!)` not covered - --> $DIR/empty-types.rs:155:15 + --> $DIR/empty-types.rs:154:15 | LL | match *ref_opt_void { | ^^^^^^^^^^^^^ pattern `Some(!)` not covered @@ -167,7 +158,7 @@ LL + Some(!) | error: unreachable pattern - --> $DIR/empty-types.rs:198:13 + --> $DIR/empty-types.rs:197:13 | LL | _ => {} | ^------ @@ -178,7 +169,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:203:13 + --> $DIR/empty-types.rs:202:13 | LL | _ => {} | ^------ @@ -189,7 +180,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:208:13 + --> $DIR/empty-types.rs:207:13 | LL | _ => {} | ^------ @@ -200,7 +191,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:213:13 + --> $DIR/empty-types.rs:212:13 | LL | _ => {} | ^------ @@ -211,7 +202,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:219:13 + --> $DIR/empty-types.rs:218:13 | LL | _ => {} | ^------ @@ -222,7 +213,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:280:9 + --> $DIR/empty-types.rs:279:9 | LL | _ => {} | ^------ @@ -233,7 +224,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:296:13 + --> $DIR/empty-types.rs:295:13 | LL | let Ok(_) = *ptr_result_never_err; | ^^^^^ pattern `Err(!)` not covered @@ -247,7 +238,7 @@ LL | if let Ok(_) = *ptr_result_never_err { todo!() }; | ++ +++++++++++ error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty - --> $DIR/empty-types.rs:315:11 + --> $DIR/empty-types.rs:314:11 | LL | match *x {} | ^^ @@ -261,7 +252,7 @@ LL ~ } | error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty - --> $DIR/empty-types.rs:317:11 + --> $DIR/empty-types.rs:316:11 | LL | match *x {} | ^^ @@ -275,7 +266,7 @@ LL ~ } | error[E0004]: non-exhaustive patterns: `Ok(!)` and `Err(!)` not covered - --> $DIR/empty-types.rs:319:11 + --> $DIR/empty-types.rs:318:11 | LL | match *x {} | ^^ patterns `Ok(!)` and `Err(!)` not covered @@ -297,7 +288,7 @@ LL ~ } | error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty - --> $DIR/empty-types.rs:321:11 + --> $DIR/empty-types.rs:320:11 | LL | match *x {} | ^^ @@ -311,7 +302,7 @@ LL ~ } | error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty - --> $DIR/empty-types.rs:326:11 + --> $DIR/empty-types.rs:325:11 | LL | match slice_never {} | ^^^^^^^^^^^ @@ -325,7 +316,7 @@ LL ~ } | error[E0004]: non-exhaustive patterns: `&[!, ..]` not covered - --> $DIR/empty-types.rs:328:11 + --> $DIR/empty-types.rs:327:11 | LL | match slice_never { | ^^^^^^^^^^^ pattern `&[!, ..]` not covered @@ -339,7 +330,7 @@ LL + &[!, ..] | error[E0004]: non-exhaustive patterns: `&[]`, `&[!]` and `&[!, !]` not covered - --> $DIR/empty-types.rs:337:11 + --> $DIR/empty-types.rs:336:11 | LL | match slice_never { | ^^^^^^^^^^^ patterns `&[]`, `&[!]` and `&[!, !]` not covered @@ -352,7 +343,7 @@ LL + &[] | &[!] | &[!, !] => todo!() | error[E0004]: non-exhaustive patterns: `&[]` and `&[!, ..]` not covered - --> $DIR/empty-types.rs:351:11 + --> $DIR/empty-types.rs:350:11 | LL | match slice_never { | ^^^^^^^^^^^ patterns `&[]` and `&[!, ..]` not covered @@ -366,7 +357,7 @@ LL + &[] | &[!, ..] => todo!() | error[E0004]: non-exhaustive patterns: type `[!]` is non-empty - --> $DIR/empty-types.rs:358:11 + --> $DIR/empty-types.rs:357:11 | LL | match *slice_never {} | ^^^^^^^^^^^^ @@ -380,7 +371,7 @@ LL ~ } | error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty - --> $DIR/empty-types.rs:387:11 + --> $DIR/empty-types.rs:386:11 | LL | match array_0_never {} | ^^^^^^^^^^^^^ @@ -394,7 +385,7 @@ LL ~ } | error: unreachable pattern - --> $DIR/empty-types.rs:394:9 + --> $DIR/empty-types.rs:393:9 | LL | [] => {} | -- matches all the relevant values @@ -402,7 +393,7 @@ LL | _ => {} | ^ no value can reach this error[E0004]: non-exhaustive patterns: `[]` not covered - --> $DIR/empty-types.rs:396:11 + --> $DIR/empty-types.rs:395:11 | LL | match array_0_never { | ^^^^^^^^^^^^^ pattern `[]` not covered @@ -416,7 +407,7 @@ LL + [] => todo!() | error[E0004]: non-exhaustive patterns: `&Some(!)` not covered - --> $DIR/empty-types.rs:450:11 + --> $DIR/empty-types.rs:449:11 | LL | match ref_opt_never { | ^^^^^^^^^^^^^ pattern `&Some(!)` not covered @@ -435,7 +426,7 @@ LL + &Some(!) | error[E0004]: non-exhaustive patterns: `Some(!)` not covered - --> $DIR/empty-types.rs:491:11 + --> $DIR/empty-types.rs:490:11 | LL | match *ref_opt_never { | ^^^^^^^^^^^^^^ pattern `Some(!)` not covered @@ -454,7 +445,7 @@ LL + Some(!) | error[E0004]: non-exhaustive patterns: `Err(!)` not covered - --> $DIR/empty-types.rs:539:11 + --> $DIR/empty-types.rs:538:11 | LL | match *ref_res_never { | ^^^^^^^^^^^^^^ pattern `Err(!)` not covered @@ -473,7 +464,7 @@ LL + Err(!) | error[E0004]: non-exhaustive patterns: `Err(!)` not covered - --> $DIR/empty-types.rs:550:11 + --> $DIR/empty-types.rs:549:11 | LL | match *ref_res_never { | ^^^^^^^^^^^^^^ pattern `Err(!)` not covered @@ -492,7 +483,7 @@ LL + Err(!) | error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty - --> $DIR/empty-types.rs:569:11 + --> $DIR/empty-types.rs:568:11 | LL | match *ref_tuple_half_never {} | ^^^^^^^^^^^^^^^^^^^^^ @@ -506,7 +497,7 @@ LL ~ } | error: unreachable pattern - --> $DIR/empty-types.rs:602:9 + --> $DIR/empty-types.rs:601:9 | LL | _ => {} | ^------ @@ -517,7 +508,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:605:9 + --> $DIR/empty-types.rs:604:9 | LL | _x => {} | ^^------ @@ -528,7 +519,7 @@ LL | _x => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:608:9 + --> $DIR/empty-types.rs:607:9 | LL | _ if false => {} | ^--------------- @@ -539,7 +530,7 @@ LL | _ if false => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:611:9 + --> $DIR/empty-types.rs:610:9 | LL | _x if false => {} | ^^--------------- @@ -550,7 +541,7 @@ LL | _x if false => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `&!` not covered - --> $DIR/empty-types.rs:636:11 + --> $DIR/empty-types.rs:635:11 | LL | match ref_never { | ^^^^^^^^^ pattern `&!` not covered @@ -566,7 +557,7 @@ LL + &! | error[E0004]: non-exhaustive patterns: `Ok(!)` not covered - --> $DIR/empty-types.rs:652:11 + --> $DIR/empty-types.rs:651:11 | LL | match *ref_result_never { | ^^^^^^^^^^^^^^^^^ pattern `Ok(!)` not covered @@ -585,7 +576,7 @@ LL + Ok(!) | error[E0004]: non-exhaustive patterns: `Some(!)` not covered - --> $DIR/empty-types.rs:672:11 + --> $DIR/empty-types.rs:671:11 | LL | match *x { | ^^ pattern `Some(!)` not covered @@ -603,7 +594,7 @@ LL ~ None => {}, LL + Some(!) | -error: aborting due to 42 previous errors; 1 warning emitted +error: aborting due to 42 previous errors Some errors have detailed explanations: E0004, E0005. For more information about an error, try `rustc --explain E0004`. diff --git a/tests/ui/pattern/usefulness/empty-types.normal.stderr b/tests/ui/pattern/usefulness/empty-types.normal.stderr index 0ed8c21199673..ba158c1176b35 100644 --- a/tests/ui/pattern/usefulness/empty-types.normal.stderr +++ b/tests/ui/pattern/usefulness/empty-types.normal.stderr @@ -1,5 +1,5 @@ error: unreachable pattern - --> $DIR/empty-types.rs:48:9 + --> $DIR/empty-types.rs:47:9 | LL | _ => {} | ^------ @@ -9,13 +9,13 @@ LL | _ => {} | = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types note: the lint level is defined here - --> $DIR/empty-types.rs:14:9 + --> $DIR/empty-types.rs:13:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/empty-types.rs:51:9 + --> $DIR/empty-types.rs:50:9 | LL | _x => {} | ^^------ @@ -26,7 +26,7 @@ LL | _x => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: type `&!` is non-empty - --> $DIR/empty-types.rs:55:11 + --> $DIR/empty-types.rs:54:11 | LL | match ref_never {} | ^^^^^^^^^ @@ -41,7 +41,7 @@ LL ~ } | error: unreachable pattern - --> $DIR/empty-types.rs:82:9 + --> $DIR/empty-types.rs:81:9 | LL | _ => {} | ^------ @@ -52,7 +52,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `Ok(_)` not covered - --> $DIR/empty-types.rs:86:11 + --> $DIR/empty-types.rs:85:11 | LL | match res_u32_never {} | ^^^^^^^^^^^^^ pattern `Ok(_)` not covered @@ -71,7 +71,7 @@ LL ~ } | error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered - --> $DIR/empty-types.rs:95:11 + --> $DIR/empty-types.rs:94:11 | LL | match res_u32_never { | ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered @@ -89,7 +89,7 @@ LL ~ Ok(1_u32..=u32::MAX) => todo!() | error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:101:9 + --> $DIR/empty-types.rs:100:9 | LL | let Ok(_x) = res_u32_never.as_ref(); | ^^^^^^ pattern `Err(_)` not covered @@ -103,7 +103,7 @@ LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() }; | ++++++++++++++++ error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:105:9 + --> $DIR/empty-types.rs:104:9 | LL | let Ok(_x) = &res_u32_never; | ^^^^^^ pattern `&Err(_)` not covered @@ -117,7 +117,7 @@ LL | let Ok(_x) = &res_u32_never else { todo!() }; | ++++++++++++++++ error: unreachable pattern - --> $DIR/empty-types.rs:131:13 + --> $DIR/empty-types.rs:130:13 | LL | _ => {} | ^------ @@ -128,7 +128,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:134:13 + --> $DIR/empty-types.rs:133:13 | LL | _ if false => {} | ^--------------- @@ -139,7 +139,7 @@ LL | _ if false => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `Some(_)` not covered - --> $DIR/empty-types.rs:155:15 + --> $DIR/empty-types.rs:154:15 | LL | match *ref_opt_void { | ^^^^^^^^^^^^^ pattern `Some(_)` not covered @@ -158,7 +158,7 @@ LL + Some(_) => todo!() | error: unreachable pattern - --> $DIR/empty-types.rs:198:13 + --> $DIR/empty-types.rs:197:13 | LL | _ => {} | ^------ @@ -169,7 +169,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:203:13 + --> $DIR/empty-types.rs:202:13 | LL | _ => {} | ^------ @@ -180,7 +180,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:208:13 + --> $DIR/empty-types.rs:207:13 | LL | _ => {} | ^------ @@ -191,7 +191,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:213:13 + --> $DIR/empty-types.rs:212:13 | LL | _ => {} | ^------ @@ -202,7 +202,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:219:13 + --> $DIR/empty-types.rs:218:13 | LL | _ => {} | ^------ @@ -213,7 +213,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:280:9 + --> $DIR/empty-types.rs:279:9 | LL | _ => {} | ^------ @@ -224,7 +224,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:296:13 + --> $DIR/empty-types.rs:295:13 | LL | let Ok(_) = *ptr_result_never_err; | ^^^^^ pattern `Err(_)` not covered @@ -238,7 +238,7 @@ LL | if let Ok(_) = *ptr_result_never_err { todo!() }; | ++ +++++++++++ error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty - --> $DIR/empty-types.rs:315:11 + --> $DIR/empty-types.rs:314:11 | LL | match *x {} | ^^ @@ -252,7 +252,7 @@ LL ~ } | error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty - --> $DIR/empty-types.rs:317:11 + --> $DIR/empty-types.rs:316:11 | LL | match *x {} | ^^ @@ -266,7 +266,7 @@ LL ~ } | error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered - --> $DIR/empty-types.rs:319:11 + --> $DIR/empty-types.rs:318:11 | LL | match *x {} | ^^ patterns `Ok(_)` and `Err(_)` not covered @@ -288,7 +288,7 @@ LL ~ } | error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty - --> $DIR/empty-types.rs:321:11 + --> $DIR/empty-types.rs:320:11 | LL | match *x {} | ^^ @@ -302,7 +302,7 @@ LL ~ } | error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty - --> $DIR/empty-types.rs:326:11 + --> $DIR/empty-types.rs:325:11 | LL | match slice_never {} | ^^^^^^^^^^^ @@ -316,7 +316,7 @@ LL ~ } | error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered - --> $DIR/empty-types.rs:328:11 + --> $DIR/empty-types.rs:327:11 | LL | match slice_never { | ^^^^^^^^^^^ pattern `&[_, ..]` not covered @@ -330,7 +330,7 @@ LL + &[_, ..] => todo!() | error[E0004]: non-exhaustive patterns: `&[]`, `&[_]` and `&[_, _]` not covered - --> $DIR/empty-types.rs:337:11 + --> $DIR/empty-types.rs:336:11 | LL | match slice_never { | ^^^^^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _]` not covered @@ -343,7 +343,7 @@ LL + &[] | &[_] | &[_, _] => todo!() | error[E0004]: non-exhaustive patterns: `&[]` and `&[_, ..]` not covered - --> $DIR/empty-types.rs:351:11 + --> $DIR/empty-types.rs:350:11 | LL | match slice_never { | ^^^^^^^^^^^ patterns `&[]` and `&[_, ..]` not covered @@ -357,7 +357,7 @@ LL + &[] | &[_, ..] => todo!() | error[E0004]: non-exhaustive patterns: type `[!]` is non-empty - --> $DIR/empty-types.rs:358:11 + --> $DIR/empty-types.rs:357:11 | LL | match *slice_never {} | ^^^^^^^^^^^^ @@ -371,7 +371,7 @@ LL ~ } | error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty - --> $DIR/empty-types.rs:387:11 + --> $DIR/empty-types.rs:386:11 | LL | match array_0_never {} | ^^^^^^^^^^^^^ @@ -385,7 +385,7 @@ LL ~ } | error: unreachable pattern - --> $DIR/empty-types.rs:394:9 + --> $DIR/empty-types.rs:393:9 | LL | [] => {} | -- matches all the relevant values @@ -393,7 +393,7 @@ LL | _ => {} | ^ no value can reach this error[E0004]: non-exhaustive patterns: `[]` not covered - --> $DIR/empty-types.rs:396:11 + --> $DIR/empty-types.rs:395:11 | LL | match array_0_never { | ^^^^^^^^^^^^^ pattern `[]` not covered @@ -407,7 +407,7 @@ LL + [] => todo!() | error[E0004]: non-exhaustive patterns: `&Some(_)` not covered - --> $DIR/empty-types.rs:450:11 + --> $DIR/empty-types.rs:449:11 | LL | match ref_opt_never { | ^^^^^^^^^^^^^ pattern `&Some(_)` not covered @@ -426,7 +426,7 @@ LL + &Some(_) => todo!() | error[E0004]: non-exhaustive patterns: `Some(_)` not covered - --> $DIR/empty-types.rs:491:11 + --> $DIR/empty-types.rs:490:11 | LL | match *ref_opt_never { | ^^^^^^^^^^^^^^ pattern `Some(_)` not covered @@ -445,7 +445,7 @@ LL + Some(_) => todo!() | error[E0004]: non-exhaustive patterns: `Err(_)` not covered - --> $DIR/empty-types.rs:539:11 + --> $DIR/empty-types.rs:538:11 | LL | match *ref_res_never { | ^^^^^^^^^^^^^^ pattern `Err(_)` not covered @@ -464,7 +464,7 @@ LL + Err(_) => todo!() | error[E0004]: non-exhaustive patterns: `Err(_)` not covered - --> $DIR/empty-types.rs:550:11 + --> $DIR/empty-types.rs:549:11 | LL | match *ref_res_never { | ^^^^^^^^^^^^^^ pattern `Err(_)` not covered @@ -483,7 +483,7 @@ LL + Err(_) => todo!() | error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty - --> $DIR/empty-types.rs:569:11 + --> $DIR/empty-types.rs:568:11 | LL | match *ref_tuple_half_never {} | ^^^^^^^^^^^^^^^^^^^^^ @@ -497,7 +497,7 @@ LL ~ } | error: unreachable pattern - --> $DIR/empty-types.rs:602:9 + --> $DIR/empty-types.rs:601:9 | LL | _ => {} | ^------ @@ -508,7 +508,7 @@ LL | _ => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:605:9 + --> $DIR/empty-types.rs:604:9 | LL | _x => {} | ^^------ @@ -519,7 +519,7 @@ LL | _x => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:608:9 + --> $DIR/empty-types.rs:607:9 | LL | _ if false => {} | ^--------------- @@ -530,7 +530,7 @@ LL | _ if false => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/empty-types.rs:611:9 + --> $DIR/empty-types.rs:610:9 | LL | _x if false => {} | ^^--------------- @@ -541,7 +541,7 @@ LL | _x if false => {} = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error[E0004]: non-exhaustive patterns: `&_` not covered - --> $DIR/empty-types.rs:636:11 + --> $DIR/empty-types.rs:635:11 | LL | match ref_never { | ^^^^^^^^^ pattern `&_` not covered @@ -557,7 +557,7 @@ LL + &_ => todo!() | error[E0004]: non-exhaustive patterns: `Ok(_)` not covered - --> $DIR/empty-types.rs:652:11 + --> $DIR/empty-types.rs:651:11 | LL | match *ref_result_never { | ^^^^^^^^^^^^^^^^^ pattern `Ok(_)` not covered @@ -576,7 +576,7 @@ LL + Ok(_) => todo!() | error[E0004]: non-exhaustive patterns: `Some(_)` not covered - --> $DIR/empty-types.rs:672:11 + --> $DIR/empty-types.rs:671:11 | LL | match *x { | ^^ pattern `Some(_)` not covered diff --git a/tests/ui/pattern/usefulness/empty-types.rs b/tests/ui/pattern/usefulness/empty-types.rs index a503295fc8741..d4fdb7c1dd46a 100644 --- a/tests/ui/pattern/usefulness/empty-types.rs +++ b/tests/ui/pattern/usefulness/empty-types.rs @@ -9,7 +9,6 @@ #![feature(never_type)] #![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))] #![cfg_attr(never_pats, feature(never_patterns))] -//[never_pats]~^ WARN the feature `never_patterns` is incomplete #![allow(dead_code, unreachable_code)] #![deny(unreachable_patterns)] diff --git a/tests/ui/pin-ergonomics/coerce-non-pointer-pin.rs b/tests/ui/pin-ergonomics/coerce-non-pointer-pin.rs index a95665f126d1e..b5a0c6e4404e6 100644 --- a/tests/ui/pin-ergonomics/coerce-non-pointer-pin.rs +++ b/tests/ui/pin-ergonomics/coerce-non-pointer-pin.rs @@ -1,7 +1,6 @@ //@ check-pass #![feature(pin_ergonomics)] -//~^ WARN the feature `pin_ergonomics` is incomplete use std::pin::Pin; diff --git a/tests/ui/pin-ergonomics/coerce-non-pointer-pin.stderr b/tests/ui/pin-ergonomics/coerce-non-pointer-pin.stderr deleted file mode 100644 index 2deb5b09884c3..0000000000000 --- a/tests/ui/pin-ergonomics/coerce-non-pointer-pin.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `pin_ergonomics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/coerce-non-pointer-pin.rs:3:12 - | -LL | #![feature(pin_ergonomics)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130494 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs index a66c446441778..8dff48de60aa5 100644 --- a/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs +++ b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs @@ -1,7 +1,6 @@ // Make sure we consider `!` to be a union read. #![feature(never_type, never_patterns)] -//~^ WARN the feature `never_patterns` is incomplete union U { a: !, diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr index d7dc7a47e7283..c415e26f6e277 100644 --- a/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr +++ b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr @@ -1,20 +1,11 @@ -warning: the feature `never_patterns` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/never-pattern-is-a-read.rs:3:24 - | -LL | #![feature(never_type, never_patterns)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #118155 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/never-pattern-is-a-read.rs:12:16 + --> $DIR/never-pattern-is-a-read.rs:11:16 | LL | let U { a: ! } = u; | ^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.rs b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.rs index eeb0777c8566a..67e5760fb242d 100644 --- a/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.rs +++ b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.rs @@ -1,6 +1,5 @@ #![feature(transmutability)] #![feature(generic_const_exprs)] -//~^ WARN the feature `generic_const_exprs` is incomplete use std::mem::{Assume, TransmuteFrom}; diff --git a/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr index 6f7e9e1bfa33c..5c59fb9e175ea 100644 --- a/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr +++ b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr @@ -1,26 +1,17 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/dont-assume-err-is-yes-issue-126377.rs:2:12 - | -LL | #![feature(generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types - --> $DIR/dont-assume-err-is-yes-issue-126377.rs:14:23 + --> $DIR/dont-assume-err-is-yes-issue-126377.rs:13:23 | LL | is_transmutable::<{}>(); | ^^ expected `bool`, found `()` error[E0277]: the trait bound `(): TransmuteFrom<(), { Assume::SAFETY }>` is not satisfied - --> $DIR/dont-assume-err-is-yes-issue-126377.rs:14:23 + --> $DIR/dont-assume-err-is-yes-issue-126377.rs:13:23 | LL | is_transmutable::<{}>(); | ^^ the nightly-only, unstable trait `TransmuteFrom<(), { Assume::SAFETY }>` is not implemented for `()` | note: required by a bound in `is_transmutable` - --> $DIR/dont-assume-err-is-yes-issue-126377.rs:9:9 + --> $DIR/dont-assume-err-is-yes-issue-126377.rs:8:9 | LL | pub fn is_transmutable() | --------------- required by a bound in this function @@ -28,7 +19,7 @@ LL | where LL | (): TransmuteFrom<(), { Assume::SAFETY }>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/non_scalar_alignment_value.rs b/tests/ui/transmutability/non_scalar_alignment_value.rs index 45c9e61fcfe28..3b21cdd1c84c3 100644 --- a/tests/ui/transmutability/non_scalar_alignment_value.rs +++ b/tests/ui/transmutability/non_scalar_alignment_value.rs @@ -1,5 +1,4 @@ #![feature(min_generic_const_args)] -//~^ WARN the feature `min_generic_const_args` is incomplete #![feature(transmutability)] diff --git a/tests/ui/transmutability/non_scalar_alignment_value.stderr b/tests/ui/transmutability/non_scalar_alignment_value.stderr index d22c6d0b27e82..99d1852b7790b 100644 --- a/tests/ui/transmutability/non_scalar_alignment_value.stderr +++ b/tests/ui/transmutability/non_scalar_alignment_value.stderr @@ -1,35 +1,26 @@ -warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/non_scalar_alignment_value.rs:1:12 - | -LL | #![feature(min_generic_const_args)] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #132980 for more information - = note: `#[warn(incomplete_features)]` on by default - error: struct expression with missing field initialiser for `alignment` - --> $DIR/non_scalar_alignment_value.rs:15:32 + --> $DIR/non_scalar_alignment_value.rs:14:32 | LL | alignment: Assume {}, | ^^^^^^^^^ error: struct expression with missing field initialiser for `lifetimes` - --> $DIR/non_scalar_alignment_value.rs:15:32 + --> $DIR/non_scalar_alignment_value.rs:14:32 | LL | alignment: Assume {}, | ^^^^^^^^^ error: struct expression with missing field initialiser for `safety` - --> $DIR/non_scalar_alignment_value.rs:15:32 + --> $DIR/non_scalar_alignment_value.rs:14:32 | LL | alignment: Assume {}, | ^^^^^^^^^ error: struct expression with missing field initialiser for `validity` - --> $DIR/non_scalar_alignment_value.rs:15:32 + --> $DIR/non_scalar_alignment_value.rs:14:32 | LL | alignment: Assume {}, | ^^^^^^^^^ -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 4 previous errors diff --git a/tests/ui/unsafe-binders/binder-sized-crit.rs b/tests/ui/unsafe-binders/binder-sized-crit.rs index 37677c0ef69b9..cda807119ef9b 100644 --- a/tests/ui/unsafe-binders/binder-sized-crit.rs +++ b/tests/ui/unsafe-binders/binder-sized-crit.rs @@ -1,7 +1,6 @@ //@ check-pass #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete use std::unsafe_binder::wrap_binder; diff --git a/tests/ui/unsafe-binders/binder-sized-crit.stderr b/tests/ui/unsafe-binders/binder-sized-crit.stderr deleted file mode 100644 index 3ba6cf2ef8c1d..0000000000000 --- a/tests/ui/unsafe-binders/binder-sized-crit.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/binder-sized-crit.rs:3:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/unsafe-binders/expr.rs b/tests/ui/unsafe-binders/expr.rs index d437d8f8ac07e..9feb29439187d 100644 --- a/tests/ui/unsafe-binders/expr.rs +++ b/tests/ui/unsafe-binders/expr.rs @@ -1,7 +1,6 @@ //@ check-pass #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete use std::unsafe_binder::{wrap_binder, unwrap_binder}; diff --git a/tests/ui/unsafe-binders/expr.stderr b/tests/ui/unsafe-binders/expr.stderr deleted file mode 100644 index 07026e18e1252..0000000000000 --- a/tests/ui/unsafe-binders/expr.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/expr.rs:3:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/unsafe-binders/lifetime-resolution.rs b/tests/ui/unsafe-binders/lifetime-resolution.rs index d243154011947..9935edffaa53f 100644 --- a/tests/ui/unsafe-binders/lifetime-resolution.rs +++ b/tests/ui/unsafe-binders/lifetime-resolution.rs @@ -1,5 +1,4 @@ #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete fn foo<'a>() { let good: unsafe<'b> &'a &'b (); diff --git a/tests/ui/unsafe-binders/lifetime-resolution.stderr b/tests/ui/unsafe-binders/lifetime-resolution.stderr index 69660c271bfc9..2f445e9a02b46 100644 --- a/tests/ui/unsafe-binders/lifetime-resolution.stderr +++ b/tests/ui/unsafe-binders/lifetime-resolution.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'missing` - --> $DIR/lifetime-resolution.rs:7:28 + --> $DIR/lifetime-resolution.rs:6:28 | LL | let missing: unsafe<> &'missing (); | ^^^^^^^^ undeclared lifetime @@ -15,7 +15,7 @@ LL | fn foo<'missing, 'a>() { | +++++++++ error[E0401]: can't use generic parameters from outer item - --> $DIR/lifetime-resolution.rs:11:30 + --> $DIR/lifetime-resolution.rs:10:30 | LL | fn foo<'a>() { | -- lifetime parameter from outer item @@ -32,16 +32,7 @@ help: consider introducing lifetime `'a` here LL | fn inner<'a, 'b>() { | +++ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/lifetime-resolution.rs:1:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors Some errors have detailed explanations: E0261, E0401. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/unsafe-binders/mismatch.rs b/tests/ui/unsafe-binders/mismatch.rs index 840d938cbe98c..8da94ccebb73f 100644 --- a/tests/ui/unsafe-binders/mismatch.rs +++ b/tests/ui/unsafe-binders/mismatch.rs @@ -1,5 +1,4 @@ #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete use std::unsafe_binder::{wrap_binder, unwrap_binder}; diff --git a/tests/ui/unsafe-binders/mismatch.stderr b/tests/ui/unsafe-binders/mismatch.stderr index f64db92eb655a..5e0720feddf01 100644 --- a/tests/ui/unsafe-binders/mismatch.stderr +++ b/tests/ui/unsafe-binders/mismatch.stderr @@ -1,14 +1,5 @@ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/mismatch.rs:1:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types - --> $DIR/mismatch.rs:7:46 + --> $DIR/mismatch.rs:6:46 | LL | let _: unsafe<'a> &'a i32 = wrap_binder!(&()); | ^^^ expected `&i32`, found `&()` @@ -17,7 +8,7 @@ LL | let _: unsafe<'a> &'a i32 = wrap_binder!(&()); found reference `&()` error: `wrap_binder!()` can only wrap into unsafe binder, not `i32` - --> $DIR/mismatch.rs:12:18 + --> $DIR/mismatch.rs:11:18 | LL | let _: i32 = wrap_binder!(&()); | ^^^^^^^^^^^^^^^^^ @@ -26,7 +17,7 @@ LL | let _: i32 = wrap_binder!(&()); = note: this error originates in the macro `wrap_binder` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected unsafe binder, found integer as input of `unwrap_binder!()` - --> $DIR/mismatch.rs:18:20 + --> $DIR/mismatch.rs:17:20 | LL | unwrap_binder!(y); | ^ @@ -34,7 +25,7 @@ LL | unwrap_binder!(y); = note: only an unsafe binder type can be unwrapped error[E0282]: type annotations needed - --> $DIR/mismatch.rs:23:9 + --> $DIR/mismatch.rs:22:9 | LL | let unknown = Default::default(); | ^^^^^^^ @@ -48,12 +39,12 @@ LL | let unknown: /* Type */ = Default::default(); | ++++++++++++ error[E0282]: type annotations needed - --> $DIR/mismatch.rs:29:26 + --> $DIR/mismatch.rs:28:26 | LL | let x = wrap_binder!(&42); | ^^^ cannot infer type -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 5 previous errors Some errors have detailed explanations: E0282, E0308. For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/unsafe-binders/moves.rs b/tests/ui/unsafe-binders/moves.rs index 9397c2bc20f97..df2cb2265e663 100644 --- a/tests/ui/unsafe-binders/moves.rs +++ b/tests/ui/unsafe-binders/moves.rs @@ -1,5 +1,4 @@ #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete use std::mem::{ManuallyDrop, drop}; use std::unsafe_binder::{unwrap_binder, wrap_binder}; diff --git a/tests/ui/unsafe-binders/moves.stderr b/tests/ui/unsafe-binders/moves.stderr index bd48015707782..a6d6380a0c52f 100644 --- a/tests/ui/unsafe-binders/moves.stderr +++ b/tests/ui/unsafe-binders/moves.stderr @@ -1,14 +1,5 @@ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/moves.rs:1:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0382]: use of moved value: `base` - --> $DIR/moves.rs:15:14 + --> $DIR/moves.rs:14:14 | LL | let base = NotCopy::default(); | ---- move occurs because `base` has type `ManuallyDrop`, which does not implement the `Copy` trait @@ -18,7 +9,7 @@ LL | drop(base); | ^^^^ value used here after move | note: if `NotCopyInner` implemented `Clone`, you could clone the value - --> $DIR/moves.rs:8:1 + --> $DIR/moves.rs:7:1 | LL | struct NotCopyInner; | ^^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type @@ -27,7 +18,7 @@ LL | let binder: unsafe<> NotCopy = wrap_binder!(base); | ---- you could clone this value error[E0382]: use of moved value: `binder` - --> $DIR/moves.rs:24:14 + --> $DIR/moves.rs:23:14 | LL | drop(unwrap_binder!(binder)); | ---------------------- value moved here @@ -38,7 +29,7 @@ LL | drop(unwrap_binder!(binder)); = note: this error originates in the macro `unwrap_binder` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0382]: use of moved value: `binder.0` - --> $DIR/moves.rs:36:14 + --> $DIR/moves.rs:35:14 | LL | drop(unwrap_binder!(binder).0); | ------------------------ value moved here @@ -48,6 +39,6 @@ LL | drop(unwrap_binder!(binder).0); | = note: move occurs because `binder.0` has type `ManuallyDrop`, which does not implement the `Copy` trait -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/unsafe-binders/simple.rs b/tests/ui/unsafe-binders/simple.rs index 6172a9e1e7bb2..99f20d6b2ec96 100644 --- a/tests/ui/unsafe-binders/simple.rs +++ b/tests/ui/unsafe-binders/simple.rs @@ -1,7 +1,6 @@ //@ check-pass #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete fn main() { let x: unsafe<'a> &'a (); diff --git a/tests/ui/unsafe-binders/simple.stderr b/tests/ui/unsafe-binders/simple.stderr deleted file mode 100644 index e4b82c12b066e..0000000000000 --- a/tests/ui/unsafe-binders/simple.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/simple.rs:3:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/unsafe-binders/type-mismatch.rs b/tests/ui/unsafe-binders/type-mismatch.rs index 9ac4e817c28b3..22937bb09e827 100644 --- a/tests/ui/unsafe-binders/type-mismatch.rs +++ b/tests/ui/unsafe-binders/type-mismatch.rs @@ -1,5 +1,4 @@ #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete fn main() { let x: unsafe<> i32 = 0; diff --git a/tests/ui/unsafe-binders/type-mismatch.stderr b/tests/ui/unsafe-binders/type-mismatch.stderr index e694b5d464d8e..6262620ff6b0a 100644 --- a/tests/ui/unsafe-binders/type-mismatch.stderr +++ b/tests/ui/unsafe-binders/type-mismatch.stderr @@ -1,14 +1,5 @@ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-mismatch.rs:1:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types - --> $DIR/type-mismatch.rs:5:27 + --> $DIR/type-mismatch.rs:4:27 | LL | let x: unsafe<> i32 = 0; | ------------ ^ expected `unsafe<> i32`, found integer @@ -19,7 +10,7 @@ LL | let x: unsafe<> i32 = 0; found type `{integer}` error[E0308]: mismatched types - --> $DIR/type-mismatch.rs:7:33 + --> $DIR/type-mismatch.rs:6:33 | LL | let x: unsafe<'a> &'a i32 = &0; | ------------------ ^^ expected `unsafe<'a> &i32`, found `&{integer}` @@ -29,6 +20,6 @@ LL | let x: unsafe<'a> &'a i32 = &0; = note: expected unsafe binder `unsafe<'a> &'a i32` found reference `&{integer}` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/unsafe-binders/unsafe-binders-debuginfo.rs b/tests/ui/unsafe-binders/unsafe-binders-debuginfo.rs index 15245d9ba4f23..21f8fe7fdf8fd 100644 --- a/tests/ui/unsafe-binders/unsafe-binders-debuginfo.rs +++ b/tests/ui/unsafe-binders/unsafe-binders-debuginfo.rs @@ -3,7 +3,6 @@ //@ compile-flags: -Cdebuginfo=2 //@ ignore-backends: gcc #![feature(unsafe_binders)] -//~^ WARN the feature `unsafe_binders` is incomplete use std::unsafe_binder::wrap_binder; fn main() { diff --git a/tests/ui/unsafe-binders/unsafe-binders-debuginfo.stderr b/tests/ui/unsafe-binders/unsafe-binders-debuginfo.stderr deleted file mode 100644 index 283b8b9c04f6f..0000000000000 --- a/tests/ui/unsafe-binders/unsafe-binders-debuginfo.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unsafe-binders-debuginfo.rs:5:12 - | -LL | #![feature(unsafe_binders)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #130516 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - From e19ad08c6dff5116ae99dd1bed43f151757640f8 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 20 Mar 2026 20:39:28 +1100 Subject: [PATCH 10/11] Use enums to clarify `DepNodeColorMap` color marking When a function's documentation has to explain the meaning of nested results and options, then it is often a good candidate for using a custom result enum instead. This commit also renames `DepNodeColorMap::try_mark` to `try_set_color`, to make it more distinct from the similarly-named `DepGraph::try_mark_green`. The difference is that `try_mark_green` is a higher-level operation that tries to determine whether a node _can_ be marked green, whereas `try_set_color` is a lower-level operation that actually records a color for the node. --- compiler/rustc_middle/src/dep_graph/graph.rs | 51 ++++++++++++++----- .../rustc_middle/src/dep_graph/serialized.rs | 25 +++++---- typos.toml | 1 + 3 files changed, 52 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/graph.rs b/compiler/rustc_middle/src/dep_graph/graph.rs index d0d7d581b4395..7823e9d62f1ff 100644 --- a/compiler/rustc_middle/src/dep_graph/graph.rs +++ b/compiler/rustc_middle/src/dep_graph/graph.rs @@ -1415,28 +1415,29 @@ impl DepNodeColorMap { if value <= DepNodeIndex::MAX_AS_U32 { Some(DepNodeIndex::from_u32(value)) } else { None } } - /// This tries to atomically mark a node green and assign `index` as the new - /// index if `green` is true, otherwise it will try to atomicaly mark it red. + /// Atomically sets the color of a previous-session dep node to either green + /// or red, if it has not already been colored. /// - /// This returns `Ok` if `index` gets assigned or the node is marked red, otherwise it returns - /// the already allocated index in `Err` if it is green already. If it was already - /// red, `Err(None)` is returned. + /// If the node already has a color, the new color is ignored, and the + /// return value indicates the existing color. #[inline(always)] - pub(super) fn try_mark( + pub(super) fn try_set_color( &self, prev_index: SerializedDepNodeIndex, - index: DepNodeIndex, - green: bool, - ) -> Result<(), Option> { - let value = &self.values[prev_index]; - match value.compare_exchange( + color: DesiredColor, + ) -> TrySetColorResult { + match self.values[prev_index].compare_exchange( COMPRESSED_UNKNOWN, - if green { index.as_u32() } else { COMPRESSED_RED }, + match color { + DesiredColor::Red => COMPRESSED_RED, + DesiredColor::Green { index } => index.as_u32(), + }, Ordering::Relaxed, Ordering::Relaxed, ) { - Ok(_) => Ok(()), - Err(v) => Err(if v == COMPRESSED_RED { None } else { Some(DepNodeIndex::from_u32(v)) }), + Ok(_) => TrySetColorResult::Success, + Err(COMPRESSED_RED) => TrySetColorResult::AlreadyRed, + Err(index) => TrySetColorResult::AlreadyGreen { index: DepNodeIndex::from_u32(index) }, } } @@ -1463,6 +1464,28 @@ impl DepNodeColorMap { } } +/// The color that [`DepNodeColorMap::try_set_color`] should try to apply to a node. +#[derive(Clone, Copy, Debug)] +pub(super) enum DesiredColor { + /// Try to mark the node red. + Red, + /// Try to mark the node green, associating it with a current-session node index. + Green { index: DepNodeIndex }, +} + +/// Return value of [`DepNodeColorMap::try_set_color`], indicating success or failure, +/// and (on failure) what the existing color is. +#[derive(Clone, Copy, Debug)] +pub(super) enum TrySetColorResult { + /// The [`DesiredColor`] was freshly applied to the node. + Success, + /// Coloring failed because the node was already marked red. + AlreadyRed, + /// Coloring failed because the node was already marked green, + /// and corresponds to node `index` in the current-session dep graph. + AlreadyGreen { index: DepNodeIndex }, +} + #[inline(never)] #[cold] pub(crate) fn print_markframe_trace(graph: &DepGraph, frame: &MarkFrame<'_>) { diff --git a/compiler/rustc_middle/src/dep_graph/serialized.rs b/compiler/rustc_middle/src/dep_graph/serialized.rs index 8a4ac4b5e5acd..7a8d25d367447 100644 --- a/compiler/rustc_middle/src/dep_graph/serialized.rs +++ b/compiler/rustc_middle/src/dep_graph/serialized.rs @@ -58,7 +58,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_session::Session; use tracing::{debug, instrument}; -use super::graph::{CurrentDepGraph, DepNodeColorMap}; +use super::graph::{CurrentDepGraph, DepNodeColorMap, DesiredColor, TrySetColorResult}; use super::retained::RetainedDepGraph; use super::{DepKind, DepNode, DepNodeIndex}; use crate::dep_graph::edges::EdgesVec; @@ -905,13 +905,14 @@ impl GraphEncoder { let mut local = self.status.local.borrow_mut(); let index = self.status.next_index(&mut *local); + let color = if is_green { DesiredColor::Green { index } } else { DesiredColor::Red }; - // Use `try_mark` to avoid racing when `send_promoted` is called concurrently + // Use `try_set_color` to avoid racing when `send_promoted` is called concurrently // on the same index. - match colors.try_mark(prev_index, index, is_green) { - Ok(()) => (), - Err(None) => panic!("dep node {:?} is unexpectedly red", prev_index), - Err(Some(dep_node_index)) => return dep_node_index, + match colors.try_set_color(prev_index, color) { + TrySetColorResult::Success => {} + TrySetColorResult::AlreadyRed => panic!("dep node {prev_index:?} is unexpectedly red"), + TrySetColorResult::AlreadyGreen { index } => return index, } self.status.bump_index(&mut *local); @@ -923,7 +924,8 @@ impl GraphEncoder { /// from the previous dep graph and expects all edges to already have a new dep node index /// assigned. /// - /// This will also ensure the dep node is marked green if `Some` is returned. + /// Tries to mark the dep node green, and returns Some if it is now green, + /// or None if had already been concurrently marked red. #[inline] pub(crate) fn send_promoted( &self, @@ -935,10 +937,10 @@ impl GraphEncoder { let mut local = self.status.local.borrow_mut(); let index = self.status.next_index(&mut *local); - // Use `try_mark_green` to avoid racing when `send_promoted` or `send_and_color` + // Use `try_set_color` to avoid racing when `send_promoted` or `send_and_color` // is called concurrently on the same index. - match colors.try_mark(prev_index, index, true) { - Ok(()) => { + match colors.try_set_color(prev_index, DesiredColor::Green { index }) { + TrySetColorResult::Success => { self.status.bump_index(&mut *local); self.status.encode_promoted_node( index, @@ -949,7 +951,8 @@ impl GraphEncoder { ); Some(index) } - Err(dep_node_index) => dep_node_index, + TrySetColorResult::AlreadyRed => None, + TrySetColorResult::AlreadyGreen { index } => Some(index), } } diff --git a/typos.toml b/typos.toml index 82e2b98f2e49c..8e14ce58dcb4f 100644 --- a/typos.toml +++ b/typos.toml @@ -48,6 +48,7 @@ unstalled = "unstalled" # short for un-stalled # the non-empty form can be automatically fixed by `--bless`. # # tidy-alphabetical-start +atomicaly = "atomically" definitinon = "definition" dependy = "" similarlty = "similarity" From 1fec51c446893ab97a04ba04ea896d29c88e421d Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 22 Mar 2026 15:10:46 +1100 Subject: [PATCH 11/11] Remove `DepNodeColorMap::insert_red` This method is only used to initialize the always-red node, which can be done with `try_set_color` instead. --- compiler/rustc_middle/src/dep_graph/graph.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/graph.rs b/compiler/rustc_middle/src/dep_graph/graph.rs index 7823e9d62f1ff..0f50abb827de2 100644 --- a/compiler/rustc_middle/src/dep_graph/graph.rs +++ b/compiler/rustc_middle/src/dep_graph/graph.rs @@ -164,9 +164,10 @@ impl DepGraph { ); assert_eq!(red_node_index, DepNodeIndex::FOREVER_RED_NODE); if prev_graph_node_count > 0 { - colors.insert_red(SerializedDepNodeIndex::from_u32( - DepNodeIndex::FOREVER_RED_NODE.as_u32(), - )); + let prev_index = + const { SerializedDepNodeIndex::from_u32(DepNodeIndex::FOREVER_RED_NODE.as_u32()) }; + let result = colors.try_set_color(prev_index, DesiredColor::Red); + assert_matches!(result, TrySetColorResult::Success); } DepGraph { @@ -1455,13 +1456,6 @@ impl DepNodeColorMap { DepNodeColor::Unknown } } - - #[inline] - pub(super) fn insert_red(&self, index: SerializedDepNodeIndex) { - let value = self.values[index].swap(COMPRESSED_RED, Ordering::Release); - // Sanity check for duplicate nodes - assert_eq!(value, COMPRESSED_UNKNOWN, "tried to color an already colored node as red"); - } } /// The color that [`DepNodeColorMap::try_set_color`] should try to apply to a node.