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 6b42ed48f77ed..80c1106780ca7 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2997,12 +2997,25 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span, "use of `const` in the type system not defined as `type const`", ); - if def_id.is_local() { + if let Some(local_def_id) = def_id.as_local() { let name = tcx.def_path_str(def_id); + let (insertion_span, sugg) = match tcx.hir_node_by_def_id(local_def_id) { + hir::Node::Item(item) if !item.vis_span.is_empty() => { + (item.vis_span.shrink_to_hi(), " type") + } + hir::Node::ImplItem(impl_item) + if let Some(vis_span) = + impl_item.vis_span().filter(|span| !span.is_empty()) => + { + (vis_span.shrink_to_hi(), " type") + } + _ => (tcx.def_span(def_id).shrink_to_lo(), "type "), + }; + err.span_suggestion_verbose( - tcx.def_span(def_id).shrink_to_lo(), + insertion_span, format!("add `type` before `const` for `{name}`"), - format!("type "), + sugg, Applicability::MaybeIncorrect, ); } else { diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index 013abab412a9d..6c639a8b092b3 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -758,7 +758,7 @@ impl u128 { /// ``` #[stable(feature = "int_format_into", since = "CURRENT_RUSTC_VERSION")] pub fn format_into(self, buf: &mut NumBuffer) -> &str { - let diff = buf.capacity() - U128_MAX_DEC_N; + let diff = buf.buf.len() - U128_MAX_DEC_N; // FIXME: Once const generics are better, use `NumberBufferTrait::BUF_SIZE` as generic const // for `fmt_u128_inner`. // @@ -790,7 +790,7 @@ impl i128 { /// ``` #[stable(feature = "int_format_into", since = "CURRENT_RUSTC_VERSION")] pub fn format_into(self, buf: &mut NumBuffer) -> &str { - let diff = buf.capacity() - U128_MAX_DEC_N; + let diff = buf.buf.len() - U128_MAX_DEC_N; // FIXME: Once const generics are better, use `NumberBufferTrait::BUF_SIZE` as generic const // for `fmt_u128_inner`. // diff --git a/library/core/src/fmt/num_buffer.rs b/library/core/src/fmt/num_buffer.rs index 4fbdd1fcd2163..af8acda6633c5 100644 --- a/library/core/src/fmt/num_buffer.rs +++ b/library/core/src/fmt/num_buffer.rs @@ -3,9 +3,12 @@ use crate::mem::MaybeUninit; /// Trait used to describe the maximum number of digits in decimal base of the implemented integer. #[unstable(feature = "fmt_internals", issue = "none")] pub trait NumBufferTrait { - /// Maximum number of digits in decimal base of the implemented integer. + /// Used for initializing the `NumberBuffer` value. #[unstable(feature = "fmt_internals", issue = "none")] - const BUF_SIZE: usize; + const DEFAULT: Self::Buf; + /// The actual underlying type. + #[unstable(feature = "fmt_internals", issue = "none")] + type Buf: AsRef<[MaybeUninit]> + AsMut<[MaybeUninit]>; } macro_rules! impl_NumBufferTrait { @@ -14,11 +17,13 @@ macro_rules! impl_NumBufferTrait { #[stable(feature = "int_format_into", since = "CURRENT_RUSTC_VERSION")] impl NumBufferTrait for $signed { // `+ 2` and not `+ 1` to include the `-` character. - const BUF_SIZE: usize = $signed::MAX.ilog(10) as usize + 2; + const DEFAULT: Self::Buf = [MaybeUninit::::uninit(); $signed::MAX.ilog(10) as usize + 2]; + type Buf = [MaybeUninit; $signed::MAX.ilog(10) as usize + 2]; } #[stable(feature = "int_format_into", since = "CURRENT_RUSTC_VERSION")] impl NumBufferTrait for $unsigned { - const BUF_SIZE: usize = $unsigned::MAX.ilog(10) as usize + 1; + const DEFAULT: Self::Buf = [MaybeUninit::::uninit(); $unsigned::MAX.ilog(10) as usize + 1]; + type Buf = [MaybeUninit; $unsigned::MAX.ilog(10) as usize + 1]; } )* } @@ -52,9 +57,7 @@ impl_NumBufferTrait! { /// ``` #[stable(feature = "int_format_into", since = "CURRENT_RUSTC_VERSION")] pub struct NumBuffer { - // FIXME: Once const generics feature is working, use `T::BUF_SIZE` instead of 40. - pub(crate) buf: [MaybeUninit; 40], - // FIXME: Remove this field once we can actually use `T`. + pub(crate) buf: T::Buf, phantom: core::marker::PhantomData, } @@ -72,10 +75,6 @@ impl NumBuffer { #[rustc_const_stable(feature = "int_format_into", since = "CURRENT_RUSTC_VERSION")] pub const fn new() -> Self { // FIXME: Once const generics feature is working, use `T::BUF_SIZE` instead of 40. - NumBuffer { buf: [MaybeUninit::::uninit(); 40], phantom: core::marker::PhantomData } - } - - pub(crate) const fn capacity(&self) -> usize { - self.buf.len() + NumBuffer { buf: T::DEFAULT, phantom: core::marker::PhantomData } } } diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index c75a974b13522..de80164ed4f85 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -626,14 +626,7 @@ impl fmt::Debug for OnceLock { impl Clone for OnceLock { #[inline] fn clone(&self) -> OnceLock { - let cell = Self::new(); - if let Some(value) = self.get() { - match cell.set(value.clone()) { - Ok(()) => (), - Err(_) => unreachable!(), - } - } - cell + self.get().cloned().map_or_default(Self::from) } } diff --git a/tests/ui/const-generics/mgca/suggest-pub-type_const.fixed b/tests/ui/const-generics/mgca/suggest-pub-type_const.fixed new file mode 100644 index 0000000000000..310cb5d17a490 --- /dev/null +++ b/tests/ui/const-generics/mgca/suggest-pub-type_const.fixed @@ -0,0 +1,53 @@ +//! Regression test for +//! Tests suggesting `pub type const` instead of `type pub const`. +//@ run-rustfix +#![feature(min_generic_const_args, inherent_associated_types)] +#![allow(dead_code)] + +mod impl_item { + pub struct Bar; + impl Bar { + pub type const PUBLIC: usize = 1; + pub(crate) type const RESTRICTED: usize = 1; + type const PRIVATE: usize = 1; + } + + pub struct Foo1([u8; Bar::PUBLIC]); + //~^ ERROR: use of `const` in the type system not defined as `type const` + pub struct Foo2([u8; Bar::RESTRICTED]); + //~^ ERROR: use of `const` in the type system not defined as `type const` + pub struct Foo3([u8; Bar::PRIVATE]); + //~^ ERROR: use of `const` in the type system not defined as `type const` +} + +mod top_level_item { + pub type const PUBLIC: usize = 1; + pub(crate) type const RESTRICTED: usize = 1; + type const PRIVATE: usize = 1; + + pub struct Foo1([u8; PUBLIC]); + //~^ ERROR: use of `const` in the type system not defined as `type const` + pub struct Foo2([u8; RESTRICTED]); + //~^ ERROR: use of `const` in the type system not defined as `type const` + pub struct Foo3([u8; PRIVATE]); + //~^ ERROR: use of `const` in the type system not defined as `type const` +} + +mod trait_item { + pub trait Foo { + type const PUBLIC: usize; + //~^ ERROR: [E0449] + type const RESTRICTED: usize; + //~^ ERROR: [E0449] + type const PRIVATE: usize; + } + + pub struct Bar([u8; T::PUBLIC]); + //~^ ERROR: use of `const` in the type system not defined as `type const` + pub struct Bar2([u8; T::RESTRICTED]); + //~^ ERROR: use of `const` in the type system not defined as `type const` + pub struct Bar3([u8; T::PRIVATE]); + //~^ ERROR: use of `const` in the type system not defined as `type const` +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/suggest-pub-type_const.rs b/tests/ui/const-generics/mgca/suggest-pub-type_const.rs new file mode 100644 index 0000000000000..0d86f47089388 --- /dev/null +++ b/tests/ui/const-generics/mgca/suggest-pub-type_const.rs @@ -0,0 +1,53 @@ +//! Regression test for +//! Tests suggesting `pub type const` instead of `type pub const`. +//@ run-rustfix +#![feature(min_generic_const_args, inherent_associated_types)] +#![allow(dead_code)] + +mod impl_item { + pub struct Bar; + impl Bar { + pub const PUBLIC: usize = 1; + pub(crate) const RESTRICTED: usize = 1; + const PRIVATE: usize = 1; + } + + pub struct Foo1([u8; Bar::PUBLIC]); + //~^ ERROR: use of `const` in the type system not defined as `type const` + pub struct Foo2([u8; Bar::RESTRICTED]); + //~^ ERROR: use of `const` in the type system not defined as `type const` + pub struct Foo3([u8; Bar::PRIVATE]); + //~^ ERROR: use of `const` in the type system not defined as `type const` +} + +mod top_level_item { + pub const PUBLIC: usize = 1; + pub(crate) const RESTRICTED: usize = 1; + const PRIVATE: usize = 1; + + pub struct Foo1([u8; PUBLIC]); + //~^ ERROR: use of `const` in the type system not defined as `type const` + pub struct Foo2([u8; RESTRICTED]); + //~^ ERROR: use of `const` in the type system not defined as `type const` + pub struct Foo3([u8; PRIVATE]); + //~^ ERROR: use of `const` in the type system not defined as `type const` +} + +mod trait_item { + pub trait Foo { + pub const PUBLIC: usize; + //~^ ERROR: [E0449] + pub(crate) const RESTRICTED: usize; + //~^ ERROR: [E0449] + const PRIVATE: usize; + } + + pub struct Bar([u8; T::PUBLIC]); + //~^ ERROR: use of `const` in the type system not defined as `type const` + pub struct Bar2([u8; T::RESTRICTED]); + //~^ ERROR: use of `const` in the type system not defined as `type const` + pub struct Bar3([u8; T::PRIVATE]); + //~^ ERROR: use of `const` in the type system not defined as `type const` +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/suggest-pub-type_const.stderr b/tests/ui/const-generics/mgca/suggest-pub-type_const.stderr new file mode 100644 index 0000000000000..17d71000cc515 --- /dev/null +++ b/tests/ui/const-generics/mgca/suggest-pub-type_const.stderr @@ -0,0 +1,118 @@ +error[E0449]: visibility qualifiers are not permitted here + --> $DIR/suggest-pub-type_const.rs:38:9 + | +LL | pub const PUBLIC: usize; + | ^^^ help: remove the qualifier + | + = note: trait items always share the visibility of their trait + +error[E0449]: visibility qualifiers are not permitted here + --> $DIR/suggest-pub-type_const.rs:40:9 + | +LL | pub(crate) const RESTRICTED: usize; + | ^^^^^^^^^^ help: remove the qualifier + | + = note: trait items always share the visibility of their trait + +error: use of `const` in the type system not defined as `type const` + --> $DIR/suggest-pub-type_const.rs:15:26 + | +LL | pub struct Foo1([u8; Bar::PUBLIC]); + | ^^^^^^^^^^^ + | +help: add `type` before `const` for `impl_item::Bar::PUBLIC` + | +LL | pub type const PUBLIC: usize = 1; + | ++++ + +error: use of `const` in the type system not defined as `type const` + --> $DIR/suggest-pub-type_const.rs:17:26 + | +LL | pub struct Foo2([u8; Bar::RESTRICTED]); + | ^^^^^^^^^^^^^^^ + | +help: add `type` before `const` for `impl_item::Bar::RESTRICTED` + | +LL | pub(crate) type const RESTRICTED: usize = 1; + | ++++ + +error: use of `const` in the type system not defined as `type const` + --> $DIR/suggest-pub-type_const.rs:19:26 + | +LL | pub struct Foo3([u8; Bar::PRIVATE]); + | ^^^^^^^^^^^^ + | +help: add `type` before `const` for `impl_item::Bar::PRIVATE` + | +LL | type const PRIVATE: usize = 1; + | ++++ + +error: use of `const` in the type system not defined as `type const` + --> $DIR/suggest-pub-type_const.rs:28:26 + | +LL | pub struct Foo1([u8; PUBLIC]); + | ^^^^^^ + | +help: add `type` before `const` for `PUBLIC` + | +LL | pub type const PUBLIC: usize = 1; + | ++++ + +error: use of `const` in the type system not defined as `type const` + --> $DIR/suggest-pub-type_const.rs:30:26 + | +LL | pub struct Foo2([u8; RESTRICTED]); + | ^^^^^^^^^^ + | +help: add `type` before `const` for `RESTRICTED` + | +LL | pub(crate) type const RESTRICTED: usize = 1; + | ++++ + +error: use of `const` in the type system not defined as `type const` + --> $DIR/suggest-pub-type_const.rs:32:26 + | +LL | pub struct Foo3([u8; PRIVATE]); + | ^^^^^^^ + | +help: add `type` before `const` for `PRIVATE` + | +LL | type const PRIVATE: usize = 1; + | ++++ + +error: use of `const` in the type system not defined as `type const` + --> $DIR/suggest-pub-type_const.rs:45:33 + | +LL | pub struct Bar([u8; T::PUBLIC]); + | ^^^^^^^^^ + | +help: add `type` before `const` for `Foo::PUBLIC` + | +LL | type pub const PUBLIC: usize; + | ++++ + +error: use of `const` in the type system not defined as `type const` + --> $DIR/suggest-pub-type_const.rs:47:34 + | +LL | pub struct Bar2([u8; T::RESTRICTED]); + | ^^^^^^^^^^^^^ + | +help: add `type` before `const` for `Foo::RESTRICTED` + | +LL | type pub(crate) const RESTRICTED: usize; + | ++++ + +error: use of `const` in the type system not defined as `type const` + --> $DIR/suggest-pub-type_const.rs:49:34 + | +LL | pub struct Bar3([u8; T::PRIVATE]); + | ^^^^^^^^^^ + | +help: add `type` before `const` for `Foo::PRIVATE` + | +LL | type const PRIVATE: usize; + | ++++ + +error: aborting due to 11 previous errors + +For more information about this error, try `rustc --explain E0449`.