Skip to content

Commit 8c75e93

Browse files
committed
Auto merge of #158162 - jhpratt:rollup-sVgABWZ, r=jhpratt
Rollup of 3 pull requests Successful merges: - #157976 (Improve `NumBufferTrait` associated items) - #157382 (Suggest `type` next to visibility for const items) - #158157 (Use the direct `From` in `Clone for OnceLock<T>`)
2 parents 32ea361 + e8809e3 commit 8c75e93

7 files changed

Lines changed: 254 additions & 25 deletions

File tree

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2997,12 +2997,25 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
29972997
span,
29982998
"use of `const` in the type system not defined as `type const`",
29992999
);
3000-
if def_id.is_local() {
3000+
if let Some(local_def_id) = def_id.as_local() {
30013001
let name = tcx.def_path_str(def_id);
3002+
let (insertion_span, sugg) = match tcx.hir_node_by_def_id(local_def_id) {
3003+
hir::Node::Item(item) if !item.vis_span.is_empty() => {
3004+
(item.vis_span.shrink_to_hi(), " type")
3005+
}
3006+
hir::Node::ImplItem(impl_item)
3007+
if let Some(vis_span) =
3008+
impl_item.vis_span().filter(|span| !span.is_empty()) =>
3009+
{
3010+
(vis_span.shrink_to_hi(), " type")
3011+
}
3012+
_ => (tcx.def_span(def_id).shrink_to_lo(), "type "),
3013+
};
3014+
30023015
err.span_suggestion_verbose(
3003-
tcx.def_span(def_id).shrink_to_lo(),
3016+
insertion_span,
30043017
format!("add `type` before `const` for `{name}`"),
3005-
format!("type "),
3018+
sugg,
30063019
Applicability::MaybeIncorrect,
30073020
);
30083021
} else {

library/core/src/fmt/num.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ impl u128 {
758758
/// ```
759759
#[stable(feature = "int_format_into", since = "CURRENT_RUSTC_VERSION")]
760760
pub fn format_into(self, buf: &mut NumBuffer<Self>) -> &str {
761-
let diff = buf.capacity() - U128_MAX_DEC_N;
761+
let diff = buf.buf.len() - U128_MAX_DEC_N;
762762
// FIXME: Once const generics are better, use `NumberBufferTrait::BUF_SIZE` as generic const
763763
// for `fmt_u128_inner`.
764764
//
@@ -790,7 +790,7 @@ impl i128 {
790790
/// ```
791791
#[stable(feature = "int_format_into", since = "CURRENT_RUSTC_VERSION")]
792792
pub fn format_into(self, buf: &mut NumBuffer<Self>) -> &str {
793-
let diff = buf.capacity() - U128_MAX_DEC_N;
793+
let diff = buf.buf.len() - U128_MAX_DEC_N;
794794
// FIXME: Once const generics are better, use `NumberBufferTrait::BUF_SIZE` as generic const
795795
// for `fmt_u128_inner`.
796796
//

library/core/src/fmt/num_buffer.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ use crate::mem::MaybeUninit;
33
/// Trait used to describe the maximum number of digits in decimal base of the implemented integer.
44
#[unstable(feature = "fmt_internals", issue = "none")]
55
pub trait NumBufferTrait {
6-
/// Maximum number of digits in decimal base of the implemented integer.
6+
/// Used for initializing the `NumberBuffer` value.
77
#[unstable(feature = "fmt_internals", issue = "none")]
8-
const BUF_SIZE: usize;
8+
const DEFAULT: Self::Buf;
9+
/// The actual underlying type.
10+
#[unstable(feature = "fmt_internals", issue = "none")]
11+
type Buf: AsRef<[MaybeUninit<u8>]> + AsMut<[MaybeUninit<u8>]>;
912
}
1013

1114
macro_rules! impl_NumBufferTrait {
@@ -14,11 +17,13 @@ macro_rules! impl_NumBufferTrait {
1417
#[stable(feature = "int_format_into", since = "CURRENT_RUSTC_VERSION")]
1518
impl NumBufferTrait for $signed {
1619
// `+ 2` and not `+ 1` to include the `-` character.
17-
const BUF_SIZE: usize = $signed::MAX.ilog(10) as usize + 2;
20+
const DEFAULT: Self::Buf = [MaybeUninit::<u8>::uninit(); $signed::MAX.ilog(10) as usize + 2];
21+
type Buf = [MaybeUninit<u8>; $signed::MAX.ilog(10) as usize + 2];
1822
}
1923
#[stable(feature = "int_format_into", since = "CURRENT_RUSTC_VERSION")]
2024
impl NumBufferTrait for $unsigned {
21-
const BUF_SIZE: usize = $unsigned::MAX.ilog(10) as usize + 1;
25+
const DEFAULT: Self::Buf = [MaybeUninit::<u8>::uninit(); $unsigned::MAX.ilog(10) as usize + 1];
26+
type Buf = [MaybeUninit<u8>; $unsigned::MAX.ilog(10) as usize + 1];
2227
}
2328
)*
2429
}
@@ -52,9 +57,7 @@ impl_NumBufferTrait! {
5257
/// ```
5358
#[stable(feature = "int_format_into", since = "CURRENT_RUSTC_VERSION")]
5459
pub struct NumBuffer<T: NumBufferTrait> {
55-
// FIXME: Once const generics feature is working, use `T::BUF_SIZE` instead of 40.
56-
pub(crate) buf: [MaybeUninit<u8>; 40],
57-
// FIXME: Remove this field once we can actually use `T`.
60+
pub(crate) buf: T::Buf,
5861
phantom: core::marker::PhantomData<T>,
5962
}
6063

@@ -72,10 +75,6 @@ impl<T: NumBufferTrait> NumBuffer<T> {
7275
#[rustc_const_stable(feature = "int_format_into", since = "CURRENT_RUSTC_VERSION")]
7376
pub const fn new() -> Self {
7477
// FIXME: Once const generics feature is working, use `T::BUF_SIZE` instead of 40.
75-
NumBuffer { buf: [MaybeUninit::<u8>::uninit(); 40], phantom: core::marker::PhantomData }
76-
}
77-
78-
pub(crate) const fn capacity(&self) -> usize {
79-
self.buf.len()
78+
NumBuffer { buf: T::DEFAULT, phantom: core::marker::PhantomData }
8079
}
8180
}

library/std/src/sync/once_lock.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -626,14 +626,7 @@ impl<T: fmt::Debug> fmt::Debug for OnceLock<T> {
626626
impl<T: Clone> Clone for OnceLock<T> {
627627
#[inline]
628628
fn clone(&self) -> OnceLock<T> {
629-
let cell = Self::new();
630-
if let Some(value) = self.get() {
631-
match cell.set(value.clone()) {
632-
Ok(()) => (),
633-
Err(_) => unreachable!(),
634-
}
635-
}
636-
cell
629+
self.get().cloned().map_or_default(Self::from)
637630
}
638631
}
639632

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//! Regression test for <https://github.com/rust-lang/rust/issues/157368>
2+
//! Tests suggesting `pub type const` instead of `type pub const`.
3+
//@ run-rustfix
4+
#![feature(min_generic_const_args, inherent_associated_types)]
5+
#![allow(dead_code)]
6+
7+
mod impl_item {
8+
pub struct Bar;
9+
impl Bar {
10+
pub type const PUBLIC: usize = 1;
11+
pub(crate) type const RESTRICTED: usize = 1;
12+
type const PRIVATE: usize = 1;
13+
}
14+
15+
pub struct Foo1([u8; Bar::PUBLIC]);
16+
//~^ ERROR: use of `const` in the type system not defined as `type const`
17+
pub struct Foo2([u8; Bar::RESTRICTED]);
18+
//~^ ERROR: use of `const` in the type system not defined as `type const`
19+
pub struct Foo3([u8; Bar::PRIVATE]);
20+
//~^ ERROR: use of `const` in the type system not defined as `type const`
21+
}
22+
23+
mod top_level_item {
24+
pub type const PUBLIC: usize = 1;
25+
pub(crate) type const RESTRICTED: usize = 1;
26+
type const PRIVATE: usize = 1;
27+
28+
pub struct Foo1([u8; PUBLIC]);
29+
//~^ ERROR: use of `const` in the type system not defined as `type const`
30+
pub struct Foo2([u8; RESTRICTED]);
31+
//~^ ERROR: use of `const` in the type system not defined as `type const`
32+
pub struct Foo3([u8; PRIVATE]);
33+
//~^ ERROR: use of `const` in the type system not defined as `type const`
34+
}
35+
36+
mod trait_item {
37+
pub trait Foo {
38+
type const PUBLIC: usize;
39+
//~^ ERROR: [E0449]
40+
type const RESTRICTED: usize;
41+
//~^ ERROR: [E0449]
42+
type const PRIVATE: usize;
43+
}
44+
45+
pub struct Bar<T: Foo>([u8; T::PUBLIC]);
46+
//~^ ERROR: use of `const` in the type system not defined as `type const`
47+
pub struct Bar2<T: Foo>([u8; T::RESTRICTED]);
48+
//~^ ERROR: use of `const` in the type system not defined as `type const`
49+
pub struct Bar3<T: Foo>([u8; T::PRIVATE]);
50+
//~^ ERROR: use of `const` in the type system not defined as `type const`
51+
}
52+
53+
fn main() {}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//! Regression test for <https://github.com/rust-lang/rust/issues/157368>
2+
//! Tests suggesting `pub type const` instead of `type pub const`.
3+
//@ run-rustfix
4+
#![feature(min_generic_const_args, inherent_associated_types)]
5+
#![allow(dead_code)]
6+
7+
mod impl_item {
8+
pub struct Bar;
9+
impl Bar {
10+
pub const PUBLIC: usize = 1;
11+
pub(crate) const RESTRICTED: usize = 1;
12+
const PRIVATE: usize = 1;
13+
}
14+
15+
pub struct Foo1([u8; Bar::PUBLIC]);
16+
//~^ ERROR: use of `const` in the type system not defined as `type const`
17+
pub struct Foo2([u8; Bar::RESTRICTED]);
18+
//~^ ERROR: use of `const` in the type system not defined as `type const`
19+
pub struct Foo3([u8; Bar::PRIVATE]);
20+
//~^ ERROR: use of `const` in the type system not defined as `type const`
21+
}
22+
23+
mod top_level_item {
24+
pub const PUBLIC: usize = 1;
25+
pub(crate) const RESTRICTED: usize = 1;
26+
const PRIVATE: usize = 1;
27+
28+
pub struct Foo1([u8; PUBLIC]);
29+
//~^ ERROR: use of `const` in the type system not defined as `type const`
30+
pub struct Foo2([u8; RESTRICTED]);
31+
//~^ ERROR: use of `const` in the type system not defined as `type const`
32+
pub struct Foo3([u8; PRIVATE]);
33+
//~^ ERROR: use of `const` in the type system not defined as `type const`
34+
}
35+
36+
mod trait_item {
37+
pub trait Foo {
38+
pub const PUBLIC: usize;
39+
//~^ ERROR: [E0449]
40+
pub(crate) const RESTRICTED: usize;
41+
//~^ ERROR: [E0449]
42+
const PRIVATE: usize;
43+
}
44+
45+
pub struct Bar<T: Foo>([u8; T::PUBLIC]);
46+
//~^ ERROR: use of `const` in the type system not defined as `type const`
47+
pub struct Bar2<T: Foo>([u8; T::RESTRICTED]);
48+
//~^ ERROR: use of `const` in the type system not defined as `type const`
49+
pub struct Bar3<T: Foo>([u8; T::PRIVATE]);
50+
//~^ ERROR: use of `const` in the type system not defined as `type const`
51+
}
52+
53+
fn main() {}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
error[E0449]: visibility qualifiers are not permitted here
2+
--> $DIR/suggest-pub-type_const.rs:38:9
3+
|
4+
LL | pub const PUBLIC: usize;
5+
| ^^^ help: remove the qualifier
6+
|
7+
= note: trait items always share the visibility of their trait
8+
9+
error[E0449]: visibility qualifiers are not permitted here
10+
--> $DIR/suggest-pub-type_const.rs:40:9
11+
|
12+
LL | pub(crate) const RESTRICTED: usize;
13+
| ^^^^^^^^^^ help: remove the qualifier
14+
|
15+
= note: trait items always share the visibility of their trait
16+
17+
error: use of `const` in the type system not defined as `type const`
18+
--> $DIR/suggest-pub-type_const.rs:15:26
19+
|
20+
LL | pub struct Foo1([u8; Bar::PUBLIC]);
21+
| ^^^^^^^^^^^
22+
|
23+
help: add `type` before `const` for `impl_item::Bar::PUBLIC`
24+
|
25+
LL | pub type const PUBLIC: usize = 1;
26+
| ++++
27+
28+
error: use of `const` in the type system not defined as `type const`
29+
--> $DIR/suggest-pub-type_const.rs:17:26
30+
|
31+
LL | pub struct Foo2([u8; Bar::RESTRICTED]);
32+
| ^^^^^^^^^^^^^^^
33+
|
34+
help: add `type` before `const` for `impl_item::Bar::RESTRICTED`
35+
|
36+
LL | pub(crate) type const RESTRICTED: usize = 1;
37+
| ++++
38+
39+
error: use of `const` in the type system not defined as `type const`
40+
--> $DIR/suggest-pub-type_const.rs:19:26
41+
|
42+
LL | pub struct Foo3([u8; Bar::PRIVATE]);
43+
| ^^^^^^^^^^^^
44+
|
45+
help: add `type` before `const` for `impl_item::Bar::PRIVATE`
46+
|
47+
LL | type const PRIVATE: usize = 1;
48+
| ++++
49+
50+
error: use of `const` in the type system not defined as `type const`
51+
--> $DIR/suggest-pub-type_const.rs:28:26
52+
|
53+
LL | pub struct Foo1([u8; PUBLIC]);
54+
| ^^^^^^
55+
|
56+
help: add `type` before `const` for `PUBLIC`
57+
|
58+
LL | pub type const PUBLIC: usize = 1;
59+
| ++++
60+
61+
error: use of `const` in the type system not defined as `type const`
62+
--> $DIR/suggest-pub-type_const.rs:30:26
63+
|
64+
LL | pub struct Foo2([u8; RESTRICTED]);
65+
| ^^^^^^^^^^
66+
|
67+
help: add `type` before `const` for `RESTRICTED`
68+
|
69+
LL | pub(crate) type const RESTRICTED: usize = 1;
70+
| ++++
71+
72+
error: use of `const` in the type system not defined as `type const`
73+
--> $DIR/suggest-pub-type_const.rs:32:26
74+
|
75+
LL | pub struct Foo3([u8; PRIVATE]);
76+
| ^^^^^^^
77+
|
78+
help: add `type` before `const` for `PRIVATE`
79+
|
80+
LL | type const PRIVATE: usize = 1;
81+
| ++++
82+
83+
error: use of `const` in the type system not defined as `type const`
84+
--> $DIR/suggest-pub-type_const.rs:45:33
85+
|
86+
LL | pub struct Bar<T: Foo>([u8; T::PUBLIC]);
87+
| ^^^^^^^^^
88+
|
89+
help: add `type` before `const` for `Foo::PUBLIC`
90+
|
91+
LL | type pub const PUBLIC: usize;
92+
| ++++
93+
94+
error: use of `const` in the type system not defined as `type const`
95+
--> $DIR/suggest-pub-type_const.rs:47:34
96+
|
97+
LL | pub struct Bar2<T: Foo>([u8; T::RESTRICTED]);
98+
| ^^^^^^^^^^^^^
99+
|
100+
help: add `type` before `const` for `Foo::RESTRICTED`
101+
|
102+
LL | type pub(crate) const RESTRICTED: usize;
103+
| ++++
104+
105+
error: use of `const` in the type system not defined as `type const`
106+
--> $DIR/suggest-pub-type_const.rs:49:34
107+
|
108+
LL | pub struct Bar3<T: Foo>([u8; T::PRIVATE]);
109+
| ^^^^^^^^^^
110+
|
111+
help: add `type` before `const` for `Foo::PRIVATE`
112+
|
113+
LL | type const PRIVATE: usize;
114+
| ++++
115+
116+
error: aborting due to 11 previous errors
117+
118+
For more information about this error, try `rustc --explain E0449`.

0 commit comments

Comments
 (0)