From 3c442b92ae2dc684e02f9668eb8c54aad55f1d9d Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 7 Nov 2014 17:16:59 -0500 Subject: [PATCH] syntax: Use UFCS in the expansion of `#[deriving(PartialOrd)]` --- src/libsyntax/ext/deriving/cmp/ord.rs | 29 +++++++++++++++++++++++---- src/test/run-pass/issue-18738.rs | 25 +++++++++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 src/test/run-pass/issue-18738.rs diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index 7cb61d295c0..8f3b1edb59f 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -107,12 +107,19 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span, let ordering = cx.expr_path(ordering); let equals_expr = cx.expr_some(span, ordering); + let partial_cmp_path = vec![ + cx.ident_of("std"), + cx.ident_of("cmp"), + cx.ident_of("PartialOrd"), + cx.ident_of("partial_cmp"), + ]; + /* Builds: - let __test = self_field1.partial_cmp(&other_field2); + let __test = ::std::cmp::PartialOrd::partial_cmp(&self_field1, &other_field1); if __test == ::std::option::Some(::std::cmp::Equal) { - let __test = self_field2.partial_cmp(&other_field2); + let __test = ::std::cmp::PartialOrd::partial_cmp(&self_field2, &other_field2); if __test == ::std::option::Some(::std::cmp::Equal) { ... } else { @@ -124,11 +131,11 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span, FIXME #6449: These `if`s could/should be `match`es. */ - cs_same_method_fold( + cs_fold( // foldr nests the if-elses correctly, leaving the first field // as the outermost one, and the last as the innermost. false, - |cx, span, old, new| { + |cx, span, old, self_f, other_fs| { // let __test = new; // if __test == Some(::std::cmp::Equal) { // old @@ -136,6 +143,20 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span, // __test // } + let new = { + let other_f = match other_fs { + [ref o_f] => o_f, + _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`"), + }; + + let args = vec![ + cx.expr_addr_of(span, self_f), + cx.expr_addr_of(span, other_f.clone()), + ]; + + cx.expr_call_global(span, partial_cmp_path.clone(), args) + }; + let assign = cx.stmt_let(span, false, test_id, new); let cond = cx.expr_binary(span, ast::BiEq, diff --git a/src/test/run-pass/issue-18738.rs b/src/test/run-pass/issue-18738.rs new file mode 100644 index 00000000000..7958b9ec117 --- /dev/null +++ b/src/test/run-pass/issue-18738.rs @@ -0,0 +1,25 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[deriving(PartialEq, PartialOrd)] +enum Test<'a> { + Int(&'a int), + Slice(&'a [u8]), +} + +#[deriving(PartialEq, PartialOrd)] +struct Version { + vendor_info: &'static str +} + +#[deriving(PartialEq, PartialOrd)] +struct Foo(&'static str); + +fn main() {}