Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4db40b9

Browse files
committedJan 27, 2025·
Start using pattern types in libcore
1 parent 633a3fe commit 4db40b9

File tree

14 files changed

+665
-65
lines changed

14 files changed

+665
-65
lines changed
 

‎compiler/rustc_borrowck/src/type_check/mod.rs

+17-13
Original file line numberDiff line numberDiff line change
@@ -2204,19 +2204,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22042204
)
22052205
}
22062206
}
2207-
// For types with no regions we can just check that the
2208-
// both operands have the same type.
2209-
ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char | ty::Float(_)
2210-
if ty_left == right.ty(body, tcx) => {}
2211-
// Other types are compared by trait methods, not by
2212-
// `Rvalue::BinaryOp`.
2213-
_ => span_mirbug!(
2214-
self,
2215-
rvalue,
2216-
"unexpected comparison types {:?} and {:?}",
2217-
ty_left,
2218-
right.ty(body, tcx)
2219-
),
2207+
_ => {
2208+
if ty_left.is_scalar() && ty_left == right.ty(body, tcx) {
2209+
2210+
// For types with no regions we can just check that the
2211+
// both operands have the same type.
2212+
} else {
2213+
// Other types are compared by trait methods, not by
2214+
// `Rvalue::BinaryOp`.
2215+
span_mirbug!(
2216+
self,
2217+
rvalue,
2218+
"unexpected comparison types {:?} and {:?}",
2219+
ty_left,
2220+
right.ty(body, tcx)
2221+
)
2222+
}
2223+
}
22202224
}
22212225
}
22222226

‎compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,18 @@ pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) ->
456456
AdtKind::Enum => enums::build_enum_type_di_node(cx, unique_type_id),
457457
},
458458
ty::Tuple(_) => build_tuple_type_di_node(cx, unique_type_id),
459-
_ => bug!("debuginfo: unexpected type in type_di_node(): {:?}", t),
459+
ty::Pat(base, _) => return type_di_node(cx, base),
460+
// FIXME(unsafe_binders): impl debug info
461+
ty::UnsafeBinder(_) => unimplemented!(),
462+
ty::Alias(..)
463+
| ty::Param(_)
464+
| ty::Bound(..)
465+
| ty::Infer(_)
466+
| ty::Placeholder(_)
467+
| ty::CoroutineWitness(..)
468+
| ty::Error(_) => {
469+
bug!("debuginfo: unexpected type in type_di_node(): {:?}", t)
470+
}
460471
};
461472

462473
{

‎compiler/rustc_lint/src/types.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -891,15 +891,15 @@ fn get_nullable_type<'tcx>(
891891
};
892892
return get_nullable_type(tcx, typing_env, inner_field_ty);
893893
}
894-
ty::Int(ty) => Ty::new_int(tcx, ty),
895-
ty::Uint(ty) => Ty::new_uint(tcx, ty),
894+
ty::Int(_) => ty,
895+
ty::Uint(_) => ty,
896896
ty::RawPtr(ty, mutbl) => Ty::new_ptr(tcx, ty, mutbl),
897897
// As these types are always non-null, the nullable equivalent of
898898
// `Option<T>` of these types are their raw pointer counterparts.
899899
ty::Ref(_region, ty, mutbl) => Ty::new_ptr(tcx, ty, mutbl),
900-
// There is no nullable equivalent for Rust's function pointers,
900+
// There is no nullable equivalent for Rust's function pointers or pattern types,
901901
// you must use an `Option<fn(..) -> _>` to represent it.
902-
ty::FnPtr(..) => ty,
902+
ty::Pat(..) | ty::FnPtr(..) => ty,
903903
// We should only ever reach this case if `ty_is_known_nonnull` is
904904
// extended to other types.
905905
ref unhandled => {

‎compiler/rustc_middle/src/ty/sty.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -1257,17 +1257,19 @@ impl<'tcx> Ty<'tcx> {
12571257
/// contents are abstract to rustc.)
12581258
#[inline]
12591259
pub fn is_scalar(self) -> bool {
1260-
matches!(
1261-
self.kind(),
1262-
Bool | Char
1263-
| Int(_)
1264-
| Float(_)
1265-
| Uint(_)
1266-
| FnDef(..)
1267-
| FnPtr(..)
1268-
| RawPtr(_, _)
1269-
| Infer(IntVar(_) | FloatVar(_))
1270-
)
1260+
match self.kind() {
1261+
Bool
1262+
| Char
1263+
| Int(_)
1264+
| Float(_)
1265+
| Uint(_)
1266+
| FnDef(..)
1267+
| FnPtr(..)
1268+
| RawPtr(_, _)
1269+
| Infer(IntVar(_) | FloatVar(_)) => true,
1270+
Pat(base, _) => base.is_scalar(),
1271+
_ => false,
1272+
}
12711273
}
12721274

12731275
/// Returns `true` if this type is a floating point type.

‎compiler/rustc_mir_transform/src/validate.rs

+3-11
Original file line numberDiff line numberDiff line change
@@ -1062,17 +1062,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
10621062
}
10631063
Eq | Lt | Le | Ne | Ge | Gt => {
10641064
for x in [a, b] {
1065-
check_kinds!(
1066-
x,
1067-
"Cannot {op:?} compare type {:?}",
1068-
ty::Bool
1069-
| ty::Char
1070-
| ty::Int(..)
1071-
| ty::Uint(..)
1072-
| ty::Float(..)
1073-
| ty::RawPtr(..)
1074-
| ty::FnPtr(..)
1075-
)
1065+
if !x.is_scalar() {
1066+
self.fail(location, format!("Cannot {op:?} compare type {x:?}"))
1067+
}
10761068
}
10771069
}
10781070
Cmp => {

‎library/core/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@
181181
#![feature(no_core)]
182182
#![feature(no_sanitize)]
183183
#![feature(optimize_attribute)]
184+
#![feature(pattern_type_macro)]
185+
#![feature(pattern_types)]
184186
#![feature(prelude_import)]
185187
#![feature(repr_simd)]
186188
#![feature(rustc_allow_const_fn_unstable)]

‎library/core/src/num/niche_types.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,28 @@ use crate::cmp::Ordering;
88
use crate::fmt;
99
use crate::hash::{Hash, Hasher};
1010
use crate::marker::StructuralPartialEq;
11+
#[cfg(not(bootstrap))]
12+
use crate::pattern_type;
1113

1214
macro_rules! define_valid_range_type {
1315
($(
1416
$(#[$m:meta])*
1517
$vis:vis struct $name:ident($int:ident as $uint:ident in $low:literal..=$high:literal);
1618
)+) => {$(
17-
#[derive(Clone, Copy, Eq)]
19+
#[derive(Clone, Copy)]
1820
#[repr(transparent)]
19-
#[rustc_layout_scalar_valid_range_start($low)]
20-
#[rustc_layout_scalar_valid_range_end($high)]
21+
#[cfg_attr(bootstrap, rustc_layout_scalar_valid_range_start($low))]
22+
#[cfg_attr(bootstrap, rustc_layout_scalar_valid_range_end($high))]
2123
$(#[$m])*
24+
#[cfg(bootstrap)]
2225
$vis struct $name($int);
2326

27+
#[derive(Clone, Copy)]
28+
#[repr(transparent)]
29+
$(#[$m])*
30+
#[cfg(not(bootstrap))]
31+
$vis struct $name(pattern_type!($int is $low..=$high));
32+
2433
const _: () = {
2534
// With the `valid_range` attributes, it's always specified as unsigned
2635
assert!(<$uint>::MIN == 0);
@@ -41,7 +50,7 @@ macro_rules! define_valid_range_type {
4150
#[inline]
4251
pub const unsafe fn new_unchecked(val: $int) -> Self {
4352
// SAFETY: Caller promised that `val` is non-zero.
44-
unsafe { $name(val) }
53+
unsafe { $name(crate::mem::transmute(val)) }
4554
}
4655

4756
#[inline]
@@ -57,6 +66,8 @@ macro_rules! define_valid_range_type {
5766
// by <https://github.com/rust-lang/compiler-team/issues/807>.
5867
impl StructuralPartialEq for $name {}
5968

69+
impl Eq for $name {}
70+
6071
impl PartialEq for $name {
6172
#[inline]
6273
fn eq(&self, other: &Self) -> bool {

‎tests/ui/consts/const-eval/raw-bytes.64bit.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ error[E0080]: it is undefined behavior to use this value
6868
--> $DIR/raw-bytes.rs:59:1
6969
|
7070
LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
71-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
71+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
7272
|
7373
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
7474
= note: the raw bytes of the constant (size: 1, align: 1) {
@@ -79,7 +79,7 @@ error[E0080]: it is undefined behavior to use this value
7979
--> $DIR/raw-bytes.rs:61:1
8080
|
8181
LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) };
82-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
82+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
8383
|
8484
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
8585
= note: the raw bytes of the constant (size: 8, align: 8) {

‎tests/ui/consts/const-eval/ub-nonnull.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ error[E0080]: it is undefined behavior to use this value
1919
--> $DIR/ub-nonnull.rs:24:1
2020
|
2121
LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
22-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
22+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
2323
|
2424
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
2525
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
@@ -30,7 +30,7 @@ error[E0080]: it is undefined behavior to use this value
3030
--> $DIR/ub-nonnull.rs:26:1
3131
|
3232
LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) };
33-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
33+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
3434
|
3535
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
3636
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {

‎tests/ui/lint/clashing-extern-fn.stderr

+128-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,94 @@
1+
warning: `extern` block uses type `(usize) is 1..=usize::MAX`, which is not FFI-safe
2+
--> $DIR/clashing-extern-fn.rs:320:36
3+
|
4+
LL | fn non_zero_usize() -> core::num::NonZero<usize>;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
6+
|
7+
= help: consider using the base type instead
8+
= note: pattern types have no C equivalent
9+
= note: `#[warn(improper_ctypes)]` on by default
10+
11+
warning: `extern` block uses type `(usize) is 1..=usize::MAX`, which is not FFI-safe
12+
--> $DIR/clashing-extern-fn.rs:341:24
13+
|
14+
LL | fn f1() -> std::num::NonZero<usize>;
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
16+
|
17+
= help: consider using the base type instead
18+
= note: pattern types have no C equivalent
19+
20+
warning: `extern` block uses type `(usize) is 1..=usize::MAX`, which is not FFI-safe
21+
--> $DIR/clashing-extern-fn.rs:350:24
22+
|
23+
LL | fn f1() -> X;
24+
| ^ not FFI-safe
25+
|
26+
= help: consider using the base type instead
27+
= note: pattern types have no C equivalent
28+
29+
warning: `extern` block uses type `(usize) is 1..=usize::MAX`, which is not FFI-safe
30+
--> $DIR/clashing-extern-fn.rs:356:24
31+
|
32+
LL | fn f2() -> std::num::NonZero<usize>;
33+
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
34+
|
35+
= help: consider using the base type instead
36+
= note: pattern types have no C equivalent
37+
38+
warning: `extern` block uses type `(usize) is 1..=usize::MAX`, which is not FFI-safe
39+
--> $DIR/clashing-extern-fn.rs:369:24
40+
|
41+
LL | fn f2() -> X;
42+
| ^ not FFI-safe
43+
|
44+
= help: consider using the base type instead
45+
= note: pattern types have no C equivalent
46+
47+
warning: `extern` block uses type `(usize) is 1..=usize::MAX`, which is not FFI-safe
48+
--> $DIR/clashing-extern-fn.rs:394:24
49+
|
50+
LL | fn f4() -> E;
51+
| ^ not FFI-safe
52+
|
53+
= help: consider using the base type instead
54+
= note: pattern types have no C equivalent
55+
56+
warning: `extern` block uses type `(usize) is 1..=usize::MAX`, which is not FFI-safe
57+
--> $DIR/clashing-extern-fn.rs:400:24
58+
|
59+
LL | fn f4() -> std::num::NonZero<usize>;
60+
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
61+
|
62+
= help: consider using the base type instead
63+
= note: pattern types have no C equivalent
64+
65+
warning: `extern` block uses type `(usize) is 1..=usize::MAX`, which is not FFI-safe
66+
--> $DIR/clashing-extern-fn.rs:420:43
67+
|
68+
LL | fn option_non_zero_usize() -> Option<core::num::NonZero<usize>>;
69+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
70+
|
71+
= help: consider using the base type instead
72+
= note: pattern types have no C equivalent
73+
74+
warning: `extern` block uses type `(isize) is 1..=-1`, which is not FFI-safe
75+
--> $DIR/clashing-extern-fn.rs:421:43
76+
|
77+
LL | fn option_non_zero_isize() -> Option<core::num::NonZero<isize>>;
78+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
79+
|
80+
= help: consider using the base type instead
81+
= note: pattern types have no C equivalent
82+
83+
warning: `extern` block uses type `(usize) is 1..=usize::MAX`, which is not FFI-safe
84+
--> $DIR/clashing-extern-fn.rs:481:46
85+
|
86+
LL | fn hidden_niche_transparent() -> Option<Transparent>;
87+
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
88+
|
89+
= help: consider using the base type instead
90+
= note: pattern types have no C equivalent
91+
192
warning: `extern` block uses type `Option<TransparentNoNiche>`, which is not FFI-safe
293
--> $DIR/clashing-extern-fn.rs:483:55
394
|
@@ -6,7 +97,6 @@ LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
697
|
798
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
899
= note: enum has no representation hint
9-
= note: `#[warn(improper_ctypes)]` on by default
10100

11101
warning: `extern` block uses type `Option<UnsafeCell<NonZero<usize>>>`, which is not FFI-safe
12102
--> $DIR/clashing-extern-fn.rs:487:46
@@ -210,6 +300,30 @@ LL | fn non_null_ptr() -> *const usize;
210300
= note: expected `unsafe extern "C" fn() -> NonNull<usize>`
211301
found `unsafe extern "C" fn() -> *const usize`
212302

303+
warning: `option_non_zero_usize` redeclared with a different signature
304+
--> $DIR/clashing-extern-fn.rs:420:13
305+
|
306+
LL | fn option_non_zero_usize() -> usize;
307+
| ------------------------------------ `option_non_zero_usize` previously declared here
308+
...
309+
LL | fn option_non_zero_usize() -> Option<core::num::NonZero<usize>>;
310+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
311+
|
312+
= note: expected `unsafe extern "C" fn() -> usize`
313+
found `unsafe extern "C" fn() -> Option<NonZero<usize>>`
314+
315+
warning: `option_non_zero_isize` redeclared with a different signature
316+
--> $DIR/clashing-extern-fn.rs:421:13
317+
|
318+
LL | fn option_non_zero_isize() -> isize;
319+
| ------------------------------------ `option_non_zero_isize` previously declared here
320+
...
321+
LL | fn option_non_zero_isize() -> Option<core::num::NonZero<isize>>;
322+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
323+
|
324+
= note: expected `unsafe extern "C" fn() -> isize`
325+
found `unsafe extern "C" fn() -> Option<NonZero<isize>>`
326+
213327
warning: `option_non_zero_usize_incorrect` redeclared with a different signature
214328
--> $DIR/clashing-extern-fn.rs:425:13
215329
|
@@ -234,6 +348,18 @@ LL | fn option_non_null_ptr_incorrect() -> *const isize;
234348
= note: expected `unsafe extern "C" fn() -> *const usize`
235349
found `unsafe extern "C" fn() -> *const isize`
236350

351+
warning: `hidden_niche_transparent` redeclared with a different signature
352+
--> $DIR/clashing-extern-fn.rs:481:13
353+
|
354+
LL | fn hidden_niche_transparent() -> usize;
355+
| --------------------------------------- `hidden_niche_transparent` previously declared here
356+
...
357+
LL | fn hidden_niche_transparent() -> Option<Transparent>;
358+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
359+
|
360+
= note: expected `unsafe extern "C" fn() -> usize`
361+
found `unsafe extern "C" fn() -> Option<Transparent>`
362+
237363
warning: `hidden_niche_transparent_no_niche` redeclared with a different signature
238364
--> $DIR/clashing-extern-fn.rs:483:13
239365
|
@@ -258,5 +384,5 @@ LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usiz
258384
= note: expected `unsafe extern "C" fn() -> usize`
259385
found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZero<usize>>>`
260386

261-
warning: 22 warnings emitted
387+
warning: 35 warnings emitted
262388

‎tests/ui/lint/invalid_value.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,6 @@ LL | let _val: (NonZero<u32>, i32) = mem::uninitialized();
333333
|
334334
= note: `std::num::NonZero<u32>` must be non-null
335335
= note: because `core::num::niche_types::NonZeroU32Inner` must be non-null
336-
= note: integers must be initialized
337336

338337
error: the type `*const dyn Send` does not permit zero-initialization
339338
--> $DIR/invalid_value.rs:97:37
@@ -430,7 +429,6 @@ note: because `std::num::NonZero<u32>` must be non-null (in this field of the on
430429
LL | Banana(NonZero<u32>),
431430
| ^^^^^^^^^^^^
432431
= note: because `core::num::niche_types::NonZeroU32Inner` must be non-null
433-
= note: integers must be initialized
434432

435433
error: the type `bool` does not permit being left uninitialized
436434
--> $DIR/invalid_value.rs:111:26

‎tests/ui/lint/lint-ctypes-enum.stderr

+397-13
Large diffs are not rendered by default.
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use std::pat::pattern_type;
2+
3+
struct Thing(pattern_type!(u32 is 1..));
4+
5+
impl Eq for Thing {}
6+
impl PartialEq for Thing {
7+
fn eq(&self, other: &Thing) -> bool {
8+
todo!()
9+
}
10+
}
11+
12+
const TWO: Thing = Thing(unsafe { std::mem::transmute(2_u32) });
13+
14+
const _: () = match TWO {
15+
TWO => {}
16+
_ => unreachable!(),
17+
};
18+
19+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
error[E0658]: use of unstable library feature `pattern_type_macro`
2+
--> $DIR/matching.rs:3:14
3+
|
4+
LL | struct Thing(pattern_type!(u32 is 1..));
5+
| ^^^^^^^^^^^^
6+
|
7+
= note: see issue #123646 <https://github.com/rust-lang/rust/issues/123646> for more information
8+
= help: add `#![feature(pattern_type_macro)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
10+
11+
error[E0658]: pattern types are unstable
12+
--> $DIR/matching.rs:3:14
13+
|
14+
LL | struct Thing(pattern_type!(u32 is 1..));
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
16+
|
17+
= note: see issue #123646 <https://github.com/rust-lang/rust/issues/123646> for more information
18+
= help: add `#![feature(pattern_types)]` to the crate attributes to enable
19+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
20+
21+
error[E0658]: use of unstable library feature `pattern_type_macro`
22+
--> $DIR/matching.rs:1:5
23+
|
24+
LL | use std::pat::pattern_type;
25+
| ^^^^^^^^^^^^^^^^^^^^^^
26+
|
27+
= note: see issue #123646 <https://github.com/rust-lang/rust/issues/123646> for more information
28+
= help: add `#![feature(pattern_type_macro)]` to the crate attributes to enable
29+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
30+
31+
error: constant of non-structural type `Thing` in a pattern
32+
--> $DIR/matching.rs:15:5
33+
|
34+
LL | struct Thing(pattern_type!(u32 is 1..));
35+
| ------------ `Thing` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
36+
...
37+
LL | const TWO: Thing = Thing(unsafe { std::mem::transmute(2_u32) });
38+
| ---------------- constant defined here
39+
...
40+
LL | TWO => {}
41+
| ^^^ constant of non-structural type
42+
|
43+
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
44+
--> $DIR/matching.rs:6:1
45+
|
46+
LL | impl PartialEq for Thing {
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^
48+
49+
error: aborting due to 4 previous errors
50+
51+
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)
Please sign in to comment.