Skip to content

Derive(PartialOrd) generates pretty bad code #49505

Closed
@nox

Description

@nox
#[automatically_derived]
#[allow(unused_qualifications)]
impl <T: ::std::cmp::PartialOrd> ::std::cmp::PartialOrd for Option<T> {
    #[inline]
    fn partial_cmp(&self, __arg_0: &Option<T>)
     -> ::std::option::Option<::std::cmp::Ordering> {
        {
            let __self_vi =
                unsafe { ::std::intrinsics::discriminant_value(&*self) } as
                    isize;
            let __arg_1_vi =
                unsafe { ::std::intrinsics::discriminant_value(&*__arg_0) } as
                    isize;
            if true && __self_vi == __arg_1_vi {
                match (&*self, &*__arg_0) {
                    (&Option::Some(ref __self_0),
                     &Option::Some(ref __arg_1_0)) =>
                    match ::std::cmp::PartialOrd::partial_cmp(&(*__self_0),
                                                              &(*__arg_1_0)) {
                        ::std::option::Option::Some(::std::cmp::Ordering::Equal)
                        =>
                        ::std::option::Option::Some(::std::cmp::Ordering::Equal),
                        __cmp => __cmp,
                    },
                    _ =>
                    ::std::option::Option::Some(::std::cmp::Ordering::Equal),
                }
            } else { __self_vi.partial_cmp(&__arg_1_vi) }
        }
    }
    #[inline]
    fn lt(&self, __arg_0: &Option<T>) -> bool {
        {
            let __self_vi =
                unsafe { ::std::intrinsics::discriminant_value(&*self) } as
                    isize;
            let __arg_1_vi =
                unsafe { ::std::intrinsics::discriminant_value(&*__arg_0) } as
                    isize;
            if true && __self_vi == __arg_1_vi {
                match (&*self, &*__arg_0) {
                    (&Option::Some(ref __self_0),
                     &Option::Some(ref __arg_1_0)) =>
                    (*__self_0) < (*__arg_1_0) ||
                        !((*__arg_1_0) < (*__self_0)) && false,
                    _ => false,
                }
            } else { __self_vi.lt(&__arg_1_vi) }
        }
    }
    #[inline]
    fn le(&self, __arg_0: &Option<T>) -> bool {
        {
            let __self_vi =
                unsafe { ::std::intrinsics::discriminant_value(&*self) } as
                    isize;
            let __arg_1_vi =
                unsafe { ::std::intrinsics::discriminant_value(&*__arg_0) } as
                    isize;
            if true && __self_vi == __arg_1_vi {
                match (&*self, &*__arg_0) {
                    (&Option::Some(ref __self_0),
                     &Option::Some(ref __arg_1_0)) =>
                    (*__self_0) < (*__arg_1_0) ||
                        !((*__arg_1_0) < (*__self_0)) && true,
                    _ => true,
                }
            } else { __self_vi.le(&__arg_1_vi) }
        }
    }
    #[inline]
    fn gt(&self, __arg_0: &Option<T>) -> bool {
        {
            let __self_vi =
                unsafe { ::std::intrinsics::discriminant_value(&*self) } as
                    isize;
            let __arg_1_vi =
                unsafe { ::std::intrinsics::discriminant_value(&*__arg_0) } as
                    isize;
            if true && __self_vi == __arg_1_vi {
                match (&*self, &*__arg_0) {
                    (&Option::Some(ref __self_0),
                     &Option::Some(ref __arg_1_0)) =>
                    (*__self_0) > (*__arg_1_0) ||
                        !((*__arg_1_0) > (*__self_0)) && false,
                    _ => false,
                }
            } else { __self_vi.gt(&__arg_1_vi) }
        }
    }
    #[inline]
    fn ge(&self, __arg_0: &Option<T>) -> bool {
        {
            let __self_vi =
                unsafe { ::std::intrinsics::discriminant_value(&*self) } as
                    isize;
            let __arg_1_vi =
                unsafe { ::std::intrinsics::discriminant_value(&*__arg_0) } as
                    isize;
            if true && __self_vi == __arg_1_vi {
                match (&*self, &*__arg_0) {
                    (&Option::Some(ref __self_0),
                     &Option::Some(ref __arg_1_0)) =>
                    (*__self_0) > (*__arg_1_0) ||
                        !((*__arg_1_0) > (*__self_0)) && true,
                    _ => true,
                }
            } else { __self_vi.ge(&__arg_1_vi) }
        }
    }
}

Instead of doing stuff such as (a > b) || !(b > a) && true in ge, rustc should probably just reuse the operator syntax by doing a >= b.

Metadata

Metadata

Assignees

Labels

C-enhancementCategory: An issue proposing an enhancement or a PR with one.I-slowIssue: Problems and improvements with respect to performance of generated code.WG-compiler-performanceWorking group: Compiler PerformanceWG-llvmWorking group: LLVM backend code generation

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions