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 d6c3e89

Browse files
committedMar 19, 2025·
Add chaining versions of lt/le/gt/ge and use them in tuple PartialOrd
1 parent b54ca0e commit d6c3e89

File tree

5 files changed

+167
-322
lines changed

5 files changed

+167
-322
lines changed
 

‎library/core/src/cmp.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ mod bytewise;
2929
pub(crate) use bytewise::BytewiseEq;
3030

3131
use self::Ordering::*;
32+
use crate::ops::ControlFlow::{self, Break, Continue};
3233

3334
/// Trait for comparisons using the equality operator.
3435
///
@@ -1446,6 +1447,54 @@ pub macro PartialOrd($item:item) {
14461447
/* compiler built-in */
14471448
}
14481449

1450+
/// Helpers for chaining together field PartialOrds into the full type's ordering.
1451+
///
1452+
/// If the two values are equal, returns `ControlFlow::Continue`.
1453+
/// If the two values are not equal, returns `ControlFlow::Break(self OP other)`.
1454+
///
1455+
/// This allows simple types like `i32` and `f64` to just emit two comparisons
1456+
/// directly, instead of needing to optimize the 3-way comparison.
1457+
///
1458+
/// Currently this is done using specialization, but it doesn't need that:
1459+
/// it could be provided methods on `PartialOrd` instead and work fine.
1460+
pub(crate) trait SpecChainingPartialOrd<Rhs>: PartialOrd<Rhs> {
1461+
fn spec_chain_lt(&self, other: &Rhs) -> ControlFlow<bool>;
1462+
fn spec_chain_le(&self, other: &Rhs) -> ControlFlow<bool>;
1463+
fn spec_chain_gt(&self, other: &Rhs) -> ControlFlow<bool>;
1464+
fn spec_chain_ge(&self, other: &Rhs) -> ControlFlow<bool>;
1465+
}
1466+
1467+
impl<T: PartialOrd<U>, U> SpecChainingPartialOrd<U> for T {
1468+
#[inline]
1469+
default fn spec_chain_lt(&self, other: &U) -> ControlFlow<bool> {
1470+
match PartialOrd::partial_cmp(self, other) {
1471+
Some(Equal) => Continue(()),
1472+
c => Break(c.is_some_and(Ordering::is_lt)),
1473+
}
1474+
}
1475+
#[inline]
1476+
default fn spec_chain_le(&self, other: &U) -> ControlFlow<bool> {
1477+
match PartialOrd::partial_cmp(self, other) {
1478+
Some(Equal) => Continue(()),
1479+
c => Break(c.is_some_and(Ordering::is_le)),
1480+
}
1481+
}
1482+
#[inline]
1483+
default fn spec_chain_gt(&self, other: &U) -> ControlFlow<bool> {
1484+
match PartialOrd::partial_cmp(self, other) {
1485+
Some(Equal) => Continue(()),
1486+
c => Break(c.is_some_and(Ordering::is_gt)),
1487+
}
1488+
}
1489+
#[inline]
1490+
default fn spec_chain_ge(&self, other: &U) -> ControlFlow<bool> {
1491+
match PartialOrd::partial_cmp(self, other) {
1492+
Some(Equal) => Continue(()),
1493+
c => Break(c.is_some_and(Ordering::is_ge)),
1494+
}
1495+
}
1496+
}
1497+
14491498
/// Compares and returns the minimum of two values.
14501499
///
14511500
/// Returns the first argument if the comparison determines them to be equal.
@@ -1741,6 +1790,7 @@ where
17411790
mod impls {
17421791
use crate::cmp::Ordering::{self, Equal, Greater, Less};
17431792
use crate::hint::unreachable_unchecked;
1793+
use crate::ops::ControlFlow::{self, Break, Continue};
17441794

17451795
macro_rules! partial_eq_impl {
17461796
($($t:ty)*) => ($(
@@ -1779,6 +1829,36 @@ mod impls {
17791829

17801830
eq_impl! { () bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
17811831

1832+
macro_rules! chaining_impl {
1833+
($t:ty) => {
1834+
// These implementations are the same for `Ord` or `PartialOrd` types
1835+
// because if either is NAN the `==` test will fail so we end up in
1836+
// the `Break` case and the comparison will correctly return `false`.
1837+
impl super::SpecChainingPartialOrd<$t> for $t {
1838+
#[inline]
1839+
fn spec_chain_lt(&self, other: &Self) -> ControlFlow<bool> {
1840+
let (lhs, rhs) = (*self, *other);
1841+
if lhs == rhs { Continue(()) } else { Break(lhs < rhs) }
1842+
}
1843+
#[inline]
1844+
fn spec_chain_le(&self, other: &Self) -> ControlFlow<bool> {
1845+
let (lhs, rhs) = (*self, *other);
1846+
if lhs == rhs { Continue(()) } else { Break(lhs <= rhs) }
1847+
}
1848+
#[inline]
1849+
fn spec_chain_gt(&self, other: &Self) -> ControlFlow<bool> {
1850+
let (lhs, rhs) = (*self, *other);
1851+
if lhs == rhs { Continue(()) } else { Break(lhs > rhs) }
1852+
}
1853+
#[inline]
1854+
fn spec_chain_ge(&self, other: &Self) -> ControlFlow<bool> {
1855+
let (lhs, rhs) = (*self, *other);
1856+
if lhs == rhs { Continue(()) } else { Break(lhs >= rhs) }
1857+
}
1858+
}
1859+
};
1860+
}
1861+
17821862
macro_rules! partial_ord_impl {
17831863
($($t:ty)*) => ($(
17841864
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1801,6 +1881,8 @@ mod impls {
18011881
#[inline(always)]
18021882
fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
18031883
}
1884+
1885+
chaining_impl!($t);
18041886
)*)
18051887
}
18061888

@@ -1840,6 +1922,8 @@ mod impls {
18401922
fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
18411923
}
18421924

1925+
chaining_impl!($t);
1926+
18431927
#[stable(feature = "rust1", since = "1.0.0")]
18441928
impl Ord for $t {
18451929
#[inline]

‎library/core/src/tuple.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// See core/src/primitive_docs.rs for documentation.
22

33
use crate::cmp::Ordering::{self, *};
4+
use crate::cmp::SpecChainingPartialOrd;
45
use crate::marker::{ConstParamTy_, StructuralPartialEq, UnsizedConstParamTy};
6+
use crate::ops::ControlFlow::{Break, Continue};
57

68
// Recursive macro for implementing n-ary tuple functions and operations
79
//
@@ -80,19 +82,19 @@ macro_rules! tuple_impls {
8082
}
8183
#[inline]
8284
fn lt(&self, other: &($($T,)+)) -> bool {
83-
lexical_ord!(lt, Less, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
85+
lexical_ord!(lt, spec_chain_lt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
8486
}
8587
#[inline]
8688
fn le(&self, other: &($($T,)+)) -> bool {
87-
lexical_ord!(le, Less, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
89+
lexical_ord!(le, spec_chain_le, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
8890
}
8991
#[inline]
9092
fn ge(&self, other: &($($T,)+)) -> bool {
91-
lexical_ord!(ge, Greater, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
93+
lexical_ord!(ge, spec_chain_ge, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
9294
}
9395
#[inline]
9496
fn gt(&self, other: &($($T,)+)) -> bool {
95-
lexical_ord!(gt, Greater, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
97+
lexical_ord!(gt, spec_chain_gt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
9698
}
9799
}
98100
}
@@ -171,15 +173,16 @@ macro_rules! maybe_tuple_doc {
171173
// `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, opt_is_lt, a1, b1,
172174
// a2, b2, a3, b3)` (and similarly for `lexical_cmp`)
173175
//
174-
// `$ne_rel` is only used to determine the result after checking that they're
175-
// not equal, so `lt` and `le` can both just use `Less`.
176+
// `$chain_rel` is the method from `SpecChainingPartialOrd` to use for all but the
177+
// final value, to produce better results for simple primitives.
176178
macro_rules! lexical_ord {
177-
($rel: ident, $ne_rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {{
178-
let c = PartialOrd::partial_cmp(&$a, &$b);
179-
if c != Some(Equal) { c == Some($ne_rel) }
180-
else { lexical_ord!($rel, $ne_rel, $($rest_a, $rest_b),+) }
179+
($rel: ident, $chain_rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {{
180+
match SpecChainingPartialOrd::$chain_rel(&$a, &$b) {
181+
Break(val) => val,
182+
Continue(()) => lexical_ord!($rel, $chain_rel, $($rest_a, $rest_b),+),
183+
}
181184
}};
182-
($rel: ident, $ne_rel: ident, $a:expr, $b:expr) => {
185+
($rel: ident, $chain_rel: ident, $a:expr, $b:expr) => {
183186
// Use the specific method for the last element
184187
PartialOrd::$rel(&$a, &$b)
185188
};

‎tests/mir-opt/pre-codegen/tuple_ord.demo_ge_partial.PreCodegen.after.mir

Lines changed: 34 additions & 201 deletions
Original file line numberDiff line numberDiff line change
@@ -6,232 +6,65 @@ fn demo_ge_partial(_1: &(f32, f32), _2: &(f32, f32)) -> bool {
66
let mut _0: bool;
77
scope 1 (inlined std::cmp::impls::<impl PartialOrd for &(f32, f32)>::le) {
88
scope 2 (inlined core::tuple::<impl PartialOrd for (f32, f32)>::le) {
9-
let mut _12: bool;
10-
let _15: std::option::Option<std::cmp::Ordering>;
11-
let _19: &f32;
12-
let _20: &f32;
9+
let mut _7: std::ops::ControlFlow<bool>;
10+
let _8: bool;
1311
scope 3 {
14-
let mut _9: &std::option::Option<std::cmp::Ordering>;
15-
let mut _13: &std::option::Option<std::cmp::Ordering>;
16-
scope 4 (inlined <Option<std::cmp::Ordering> as PartialEq>::ne) {
17-
let mut _11: bool;
18-
scope 5 (inlined <Option<std::cmp::Ordering> as PartialEq>::eq) {
19-
let mut _10: isize;
20-
let mut _16: isize;
21-
scope 6 {
22-
scope 7 (inlined <std::cmp::Ordering as PartialEq>::eq) {
23-
let _17: i8;
24-
scope 8 {
25-
let _18: i8;
26-
scope 9 {
27-
}
28-
}
29-
}
30-
}
31-
}
32-
}
33-
scope 10 (inlined <Option<std::cmp::Ordering> as PartialEq>::eq) {
34-
let mut _14: isize;
35-
let mut _21: isize;
36-
scope 11 {
37-
scope 12 (inlined <std::cmp::Ordering as PartialEq>::eq) {
38-
let _22: i8;
39-
scope 13 {
40-
let _23: i8;
41-
scope 14 {
42-
}
43-
}
44-
}
45-
}
46-
}
4712
}
48-
scope 15 (inlined std::cmp::impls::<impl PartialOrd for f32>::partial_cmp) {
13+
scope 4 (inlined std::cmp::impls::<impl std::cmp::SpecChainingPartialOrd<f32> for f32>::spec_chain_le) {
4914
let mut _3: f32;
5015
let mut _4: f32;
5116
let mut _5: bool;
52-
let mut _6: f32;
53-
let mut _7: f32;
54-
let mut _8: bool;
17+
let mut _6: bool;
18+
scope 5 {
19+
}
20+
}
21+
scope 6 (inlined std::cmp::impls::<impl PartialOrd for f32>::le) {
22+
let mut _9: f32;
23+
let mut _10: f32;
5524
}
5625
}
5726
}
5827

5928
bb0: {
60-
StorageLive(_19);
61-
StorageLive(_20);
62-
StorageLive(_13);
63-
StorageLive(_9);
64-
StorageLive(_15);
65-
StorageLive(_5);
66-
StorageLive(_8);
29+
StorageLive(_7);
6730
StorageLive(_3);
68-
_3 = copy ((*_1).0: f32);
6931
StorageLive(_4);
32+
_3 = copy ((*_1).0: f32);
7033
_4 = copy ((*_2).0: f32);
71-
_5 = Le(move _3, move _4);
72-
StorageDead(_4);
73-
StorageDead(_3);
74-
StorageLive(_6);
75-
_6 = copy ((*_1).0: f32);
76-
StorageLive(_7);
77-
_7 = copy ((*_2).0: f32);
78-
_8 = Ge(move _6, move _7);
79-
StorageDead(_7);
80-
StorageDead(_6);
81-
switchInt(copy _5) -> [0: bb1, otherwise: bb5];
34+
StorageLive(_5);
35+
_5 = Eq(copy _3, copy _4);
36+
switchInt(move _5) -> [0: bb1, otherwise: bb2];
8237
}
8338

8439
bb1: {
85-
switchInt(copy _8) -> [0: bb2, otherwise: bb4];
40+
StorageLive(_6);
41+
_6 = Le(copy _3, copy _4);
42+
_7 = ControlFlow::<bool>::Break(move _6);
43+
StorageDead(_6);
44+
StorageDead(_5);
45+
StorageDead(_4);
46+
StorageDead(_3);
47+
_8 = copy ((_7 as Break).0: bool);
48+
_0 = copy _8;
49+
goto -> bb3;
8650
}
8751

8852
bb2: {
89-
StorageDead(_8);
9053
StorageDead(_5);
91-
StorageLive(_12);
92-
_9 = const core::tuple::<impl std::cmp::PartialOrd for (f32, f32)>::le::promoted[1];
93-
StorageLive(_11);
94-
StorageLive(_16);
54+
StorageDead(_4);
55+
StorageDead(_3);
56+
StorageLive(_9);
57+
_9 = copy ((*_1).1: f32);
9558
StorageLive(_10);
96-
_10 = discriminant((*_9));
97-
_11 = Eq(copy _10, const 0_isize);
59+
_10 = copy ((*_2).1: f32);
60+
_0 = Le(move _9, move _10);
9861
StorageDead(_10);
99-
StorageDead(_16);
100-
_12 = Not(move _11);
101-
StorageDead(_11);
102-
switchInt(move _12) -> [0: bb11, otherwise: bb3];
62+
StorageDead(_9);
63+
goto -> bb3;
10364
}
10465

10566
bb3: {
106-
_13 = const core::tuple::<impl std::cmp::PartialOrd for (f32, f32)>::le::promoted[0];
107-
StorageLive(_21);
108-
StorageLive(_14);
109-
_14 = discriminant((*_13));
110-
_0 = Eq(copy _14, const 0_isize);
111-
goto -> bb16;
112-
}
113-
114-
bb4: {
115-
_15 = const Option::<std::cmp::Ordering>::Some(Greater);
116-
StorageDead(_8);
117-
StorageDead(_5);
118-
StorageLive(_12);
119-
_9 = const core::tuple::<impl std::cmp::PartialOrd for (f32, f32)>::le::promoted[1];
120-
StorageLive(_11);
121-
StorageLive(_16);
122-
StorageLive(_10);
123-
goto -> bb8;
124-
}
125-
126-
bb5: {
127-
switchInt(copy _8) -> [0: bb6, otherwise: bb7];
128-
}
129-
130-
bb6: {
131-
_15 = const Option::<std::cmp::Ordering>::Some(Less);
132-
StorageDead(_8);
133-
StorageDead(_5);
134-
StorageLive(_12);
135-
_9 = const core::tuple::<impl std::cmp::PartialOrd for (f32, f32)>::le::promoted[1];
136-
StorageLive(_11);
137-
StorageLive(_16);
138-
StorageLive(_10);
139-
goto -> bb8;
140-
}
141-
142-
bb7: {
143-
_15 = const Option::<std::cmp::Ordering>::Some(Equal);
144-
StorageDead(_8);
145-
StorageDead(_5);
146-
StorageLive(_12);
147-
_9 = const core::tuple::<impl std::cmp::PartialOrd for (f32, f32)>::le::promoted[1];
148-
StorageLive(_11);
149-
StorageLive(_16);
150-
StorageLive(_10);
151-
goto -> bb8;
152-
}
153-
154-
bb8: {
155-
_16 = discriminant((*_9));
156-
switchInt(move _16) -> [0: bb9, 1: bb10, otherwise: bb18];
157-
}
158-
159-
bb9: {
160-
StorageDead(_10);
161-
StorageDead(_16);
162-
StorageDead(_11);
163-
_13 = const core::tuple::<impl std::cmp::PartialOrd for (f32, f32)>::le::promoted[0];
164-
StorageLive(_21);
165-
StorageLive(_14);
166-
goto -> bb13;
167-
}
168-
169-
bb10: {
170-
StorageLive(_17);
171-
StorageLive(_18);
172-
_17 = discriminant(((_15 as Some).0: std::cmp::Ordering));
173-
_18 = discriminant((((*_9) as Some).0: std::cmp::Ordering));
174-
_11 = Eq(copy _17, copy _18);
175-
StorageDead(_18);
176-
StorageDead(_17);
177-
StorageDead(_10);
178-
StorageDead(_16);
179-
_12 = Not(move _11);
180-
StorageDead(_11);
181-
switchInt(move _12) -> [0: bb11, otherwise: bb12];
182-
}
183-
184-
bb11: {
185-
_19 = &((*_1).1: f32);
186-
_20 = &((*_2).1: f32);
187-
_0 = <f32 as PartialOrd>::le(move _19, move _20) -> [return: bb17, unwind continue];
188-
}
189-
190-
bb12: {
191-
_13 = const core::tuple::<impl std::cmp::PartialOrd for (f32, f32)>::le::promoted[0];
192-
StorageLive(_21);
193-
StorageLive(_14);
194-
goto -> bb13;
195-
}
196-
197-
bb13: {
198-
_21 = discriminant((*_13));
199-
switchInt(move _21) -> [0: bb14, 1: bb15, otherwise: bb18];
200-
}
201-
202-
bb14: {
203-
_0 = const false;
204-
goto -> bb16;
205-
}
206-
207-
bb15: {
208-
StorageLive(_22);
209-
StorageLive(_23);
210-
_22 = discriminant(((_15 as Some).0: std::cmp::Ordering));
211-
_23 = discriminant((((*_13) as Some).0: std::cmp::Ordering));
212-
_0 = Eq(copy _22, copy _23);
213-
StorageDead(_23);
214-
StorageDead(_22);
215-
goto -> bb16;
216-
}
217-
218-
bb16: {
219-
StorageDead(_14);
220-
StorageDead(_21);
221-
goto -> bb17;
222-
}
223-
224-
bb17: {
225-
StorageDead(_12);
226-
StorageDead(_15);
227-
StorageDead(_9);
228-
StorageDead(_13);
229-
StorageDead(_20);
230-
StorageDead(_19);
67+
StorageDead(_7);
23168
return;
23269
}
233-
234-
bb18: {
235-
unreachable;
236-
}
23770
}

‎tests/mir-opt/pre-codegen/tuple_ord.demo_le_total.PreCodegen.after.mir

Lines changed: 34 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -6,140 +6,65 @@ fn demo_le_total(_1: &(u16, i16), _2: &(u16, i16)) -> bool {
66
let mut _0: bool;
77
scope 1 (inlined std::cmp::impls::<impl PartialOrd for &(u16, i16)>::le) {
88
scope 2 (inlined core::tuple::<impl PartialOrd for (u16, i16)>::le) {
9-
let mut _12: bool;
10-
let _13: &i16;
11-
let _14: &i16;
9+
let mut _7: std::ops::ControlFlow<bool>;
10+
let _8: bool;
1211
scope 3 {
13-
let mut _6: &std::option::Option<std::cmp::Ordering>;
14-
let mut _8: &std::option::Option<std::cmp::Ordering>;
15-
scope 4 (inlined <Option<std::cmp::Ordering> as PartialEq>::ne) {
16-
let mut _11: bool;
17-
scope 5 (inlined <Option<std::cmp::Ordering> as PartialEq>::eq) {
18-
let mut _7: isize;
19-
scope 6 {
20-
scope 7 (inlined <std::cmp::Ordering as PartialEq>::eq) {
21-
let _9: i8;
22-
scope 8 {
23-
let _10: i8;
24-
scope 9 {
25-
}
26-
}
27-
}
28-
}
29-
}
30-
}
31-
scope 10 (inlined <Option<std::cmp::Ordering> as PartialEq>::eq) {
32-
let mut _15: isize;
33-
scope 11 {
34-
scope 12 (inlined <std::cmp::Ordering as PartialEq>::eq) {
35-
let _16: i8;
36-
scope 13 {
37-
let _17: i8;
38-
scope 14 {
39-
}
40-
}
41-
}
42-
}
43-
}
4412
}
45-
scope 15 (inlined std::cmp::impls::<impl PartialOrd for u16>::partial_cmp) {
13+
scope 4 (inlined std::cmp::impls::<impl std::cmp::SpecChainingPartialOrd<u16> for u16>::spec_chain_le) {
4614
let mut _3: u16;
4715
let mut _4: u16;
48-
let mut _5: std::cmp::Ordering;
16+
let mut _5: bool;
17+
let mut _6: bool;
18+
scope 5 {
19+
}
20+
}
21+
scope 6 (inlined std::cmp::impls::<impl PartialOrd for i16>::le) {
22+
let mut _9: i16;
23+
let mut _10: i16;
4924
}
5025
}
5126
}
5227

5328
bb0: {
54-
StorageLive(_13);
55-
StorageLive(_14);
56-
StorageLive(_8);
57-
StorageLive(_6);
29+
StorageLive(_7);
5830
StorageLive(_3);
59-
_3 = copy ((*_1).0: u16);
6031
StorageLive(_4);
32+
_3 = copy ((*_1).0: u16);
6133
_4 = copy ((*_2).0: u16);
62-
_5 = Cmp(move _3, move _4);
63-
StorageDead(_4);
64-
StorageDead(_3);
65-
StorageLive(_12);
66-
_6 = const core::tuple::<impl std::cmp::PartialOrd for (u16, i16)>::le::promoted[1];
67-
StorageLive(_11);
68-
StorageLive(_7);
69-
_7 = discriminant((*_6));
70-
switchInt(move _7) -> [0: bb1, 1: bb2, otherwise: bb10];
34+
StorageLive(_5);
35+
_5 = Eq(copy _3, copy _4);
36+
switchInt(move _5) -> [0: bb1, otherwise: bb2];
7137
}
7238

7339
bb1: {
74-
StorageDead(_7);
75-
StorageDead(_11);
76-
_8 = const core::tuple::<impl std::cmp::PartialOrd for (u16, i16)>::le::promoted[0];
77-
StorageLive(_15);
78-
goto -> bb5;
40+
StorageLive(_6);
41+
_6 = Le(copy _3, copy _4);
42+
_7 = ControlFlow::<bool>::Break(move _6);
43+
StorageDead(_6);
44+
StorageDead(_5);
45+
StorageDead(_4);
46+
StorageDead(_3);
47+
_8 = copy ((_7 as Break).0: bool);
48+
_0 = copy _8;
49+
goto -> bb3;
7950
}
8051

8152
bb2: {
53+
StorageDead(_5);
54+
StorageDead(_4);
55+
StorageDead(_3);
8256
StorageLive(_9);
57+
_9 = copy ((*_1).1: i16);
8358
StorageLive(_10);
84-
_9 = discriminant(_5);
85-
_10 = discriminant((((*_6) as Some).0: std::cmp::Ordering));
86-
_11 = Eq(copy _9, copy _10);
59+
_10 = copy ((*_2).1: i16);
60+
_0 = Le(move _9, move _10);
8761
StorageDead(_10);
8862
StorageDead(_9);
89-
StorageDead(_7);
90-
_12 = Not(move _11);
91-
StorageDead(_11);
92-
switchInt(move _12) -> [0: bb3, otherwise: bb4];
63+
goto -> bb3;
9364
}
9465

9566
bb3: {
96-
_13 = &((*_1).1: i16);
97-
_14 = &((*_2).1: i16);
98-
_0 = <i16 as PartialOrd>::le(move _13, move _14) -> [return: bb9, unwind continue];
99-
}
100-
101-
bb4: {
102-
_8 = const core::tuple::<impl std::cmp::PartialOrd for (u16, i16)>::le::promoted[0];
103-
StorageLive(_15);
104-
goto -> bb5;
105-
}
106-
107-
bb5: {
108-
_15 = discriminant((*_8));
109-
switchInt(move _15) -> [0: bb6, 1: bb7, otherwise: bb10];
110-
}
111-
112-
bb6: {
113-
_0 = const false;
114-
goto -> bb8;
115-
}
116-
117-
bb7: {
118-
StorageLive(_16);
119-
StorageLive(_17);
120-
_16 = discriminant(_5);
121-
_17 = discriminant((((*_8) as Some).0: std::cmp::Ordering));
122-
_0 = Eq(copy _16, copy _17);
123-
StorageDead(_17);
124-
StorageDead(_16);
125-
goto -> bb8;
126-
}
127-
128-
bb8: {
129-
StorageDead(_15);
130-
goto -> bb9;
131-
}
132-
133-
bb9: {
134-
StorageDead(_12);
135-
StorageDead(_6);
136-
StorageDead(_8);
137-
StorageDead(_14);
138-
StorageDead(_13);
67+
StorageDead(_7);
13968
return;
14069
}
141-
142-
bb10: {
143-
unreachable;
144-
}
14570
}

‎tests/mir-opt/pre-codegen/tuple_ord.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0 -Z inline-mir-hint-threshold=9999
1+
//@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0
22
//@ needs-unwind
33

44
#![crate_type = "lib"]

0 commit comments

Comments
 (0)
Please sign in to comment.