From 6eb4f0f7fd44026a2353a620dee39d379a8e4a29 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 16 Apr 2018 23:32:28 +0100 Subject: Ensure derive(PartialOrd) is no longer accidentally exponential Previously, two comparison operations would be generated for each field, each of which could delegate to another derived PartialOrd. Now we use ordering and optional chaining to ensure each pair of fields is only compared once. --- src/etc/generate-deriving-span-tests.py | 2 +- src/libsyntax_ext/deriving/cmp/partial_ord.rs | 153 +++++++++++---------- .../derives-span-PartialOrd-enum-struct-variant.rs | 3 - .../compile-fail/derives-span-PartialOrd-enum.rs | 3 - .../compile-fail/derives-span-PartialOrd-struct.rs | 3 - .../derives-span-PartialOrd-tuple-struct.rs | 3 - src/test/compile-fail/range_traits-1.rs | 20 +-- 7 files changed, 90 insertions(+), 97 deletions(-) (limited to 'src') diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py index edb9389c00c..e248f471395 100755 --- a/src/etc/generate-deriving-span-tests.py +++ b/src/etc/generate-deriving-span-tests.py @@ -122,7 +122,7 @@ traits = { for (trait, supers, errs) in [('Clone', [], 1), ('PartialEq', [], 2), - ('PartialOrd', ['PartialEq'], 5), + ('PartialOrd', ['PartialEq'], 2), ('Eq', ['PartialEq'], 1), ('Ord', ['Eq', 'PartialOrd', 'PartialEq'], 1), ('Debug', [], 1), diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs index d71527fd0ed..b352e4b0a7e 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs @@ -14,7 +14,7 @@ use deriving::{path_local, pathvec_std, path_std}; use deriving::generic::*; use deriving::generic::ty::*; -use syntax::ast::{self, BinOpKind, Expr, MetaItem}; +use syntax::ast::{self, BinOpKind, Expr, MetaItem, Ident}; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; use syntax::ptr::P; @@ -147,34 +147,37 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P< // as the outermost one, and the last as the innermost. false, |cx, span, old, self_f, other_fs| { - // match new { - // Some(::std::cmp::Ordering::Equal) => old, - // cmp => cmp - // } + // match new { + // Some(::std::cmp::Ordering::Equal) => old, + // cmp => cmp + // } - let new = { - let other_f = match (other_fs.len(), other_fs.get(0)) { - (1, Some(o_f)) => o_f, - _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`"), - }; + let new = { + let other_f = match (other_fs.len(), other_fs.get(0)) { + (1, Some(o_f)) => o_f, + _ => { + cx.span_bug(span, + "not exactly 2 arguments in `derive(PartialOrd)`") + } + }; - let args = vec![ - cx.expr_addr_of(span, self_f), - cx.expr_addr_of(span, other_f.clone()), - ]; + 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) - }; + cx.expr_call_global(span, partial_cmp_path.clone(), args) + }; - let eq_arm = cx.arm(span, - vec![cx.pat_some(span, cx.pat_path(span, ordering.clone()))], - old); - let neq_arm = cx.arm(span, - vec![cx.pat_ident(span, test_id)], - cx.expr_ident(span, test_id)); + let eq_arm = cx.arm(span, + vec![cx.pat_some(span, cx.pat_path(span, ordering.clone()))], + old); + let neq_arm = cx.arm(span, + vec![cx.pat_ident(span, test_id)], + cx.expr_ident(span, test_id)); - cx.expr_match(span, new, vec![eq_arm, neq_arm]) - }, + cx.expr_match(span, new, vec![eq_arm, neq_arm]) + }, equals_expr.clone(), Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| { if self_args.len() != 2 { @@ -189,78 +192,77 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P< } /// Strict inequality. -fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P { - let strict_op = if less { BinOpKind::Lt } else { BinOpKind::Gt }; - cs_fold1(false, // need foldr, +fn cs_op(less: bool, + inclusive: bool, + cx: &mut ExtCtxt, + span: Span, + substr: &Substructure) -> P { + let ordering_path = |cx: &mut ExtCtxt, name: &str| { + cx.expr_path(cx.path_global(span, cx.std_path(&["cmp", "Ordering", name]))) + }; + + let par_cmp = |cx: &mut ExtCtxt, span: Span, self_f: P, other_fs: &[P]| { + let other_f = match (other_fs.len(), other_fs.get(0)) { + (1, Some(o_f)) => o_f, + _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`"), + }; + + // `self.fi.partial_cmp(other.fi)` + let cmp = cx.expr_method_call(span, + cx.expr_addr_of(span, self_f), + Ident::from_str("partial_cmp"), + vec![cx.expr_addr_of(span, other_f.clone())]); + + let default = ordering_path(cx, if less { "Greater" } else { "Less" }); + // `_.unwrap_or(Ordering::Greater/Less)` + cx.expr_method_call(span, cmp, Ident::from_str("unwrap_or"), vec![default]) + }; + + let fold = cs_fold1(false, // need foldr |cx, span, subexpr, self_f, other_fs| { - // build up a series of chain ||'s and &&'s from the inside + // build up a series of `partial_cmp`s from the inside // out (hence foldr) to get lexical ordering, i.e. for op == // `ast::lt` // // ``` - // self.f1 < other.f1 || (!(other.f1 < self.f1) && - // self.f2 < other.f2 - // ) + // self.f1.partial_cmp(other.f1).unwrap_or(Ordering::Greater) + // .then_with(|| self.f2.partial_cmp(other.f2).unwrap_or(Ordering::Greater)) + // == Ordering::Less // ``` // // and for op == // `ast::le` // // ``` - // self.f1 < other.f1 || (self.f1 == other.f1 && - // self.f2 <= other.f2 - // ) + // self.f1.partial_cmp(other.f1).unwrap_or(Ordering::Greater) + // .then_with(|| self.f2.partial_cmp(other.f2).unwrap_or(Ordering::Greater)) + // != Ordering::Greater // ``` // // The optimiser should remove the redundancy. We explicitly // get use the binops to avoid auto-deref dereferencing too many // layers of pointers, if the type includes pointers. - // - let other_f = match (other_fs.len(), other_fs.get(0)) { - (1, Some(o_f)) => o_f, - _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`"), - }; - let strict_ineq = cx.expr_binary(span, strict_op, self_f.clone(), other_f.clone()); + // `self.fi.partial_cmp(other.fi).unwrap_or(Ordering::Greater/Less)` + let par_cmp = par_cmp(cx, span, self_f, other_fs); - let deleg_cmp = if !equal { - cx.expr_unary(span, - ast::UnOp::Not, - cx.expr_binary(span, strict_op, other_f.clone(), self_f)) - } else { - cx.expr_binary(span, BinOpKind::Eq, self_f, other_f.clone()) - }; - - let and = cx.expr_binary(span, BinOpKind::And, deleg_cmp, subexpr); - cx.expr_binary(span, BinOpKind::Or, strict_ineq, and) + // `self.fi.partial_cmp(other.fi).unwrap_or(Ordering::Greater/Less).then_with(...)` + cx.expr_method_call(span, + par_cmp, + Ident::from_str("then_with"), + vec![cx.lambda0(span, subexpr)]) }, |cx, args| { match args { - Some((span, self_f, other_fs)) => { - // Special-case the base case to generate cleaner code with - // fewer operations (e.g. `<=` instead of `<` and `==`). - let other_f = match (other_fs.len(), other_fs.get(0)) { - (1, Some(o_f)) => o_f, - _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`"), - }; - - let op = match (less, equal) { - (false, false) => BinOpKind::Gt, - (false, true) => BinOpKind::Ge, - (true, false) => BinOpKind::Lt, - (true, true) => BinOpKind::Le, - }; - - cx.expr_binary(span, op, self_f, other_f.clone()) - } - None => cx.expr_bool(span, equal) + Some((span, self_f, other_fs)) => par_cmp(cx, span, self_f, other_fs), + None => ordering_path(cx, if less { "Less" } else { "Equal" }) } }, Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| { if self_args.len() != 2 { cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`") } else { - let op = match (less, equal) { + let op = match (less, inclusive) { (false, false) => GtOp, (false, true) => GeOp, (true, false) => LtOp, @@ -271,5 +273,16 @@ fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span, substr: &Substru }), cx, span, - substr) + substr); + + match *substr.fields { + EnumMatching(..) | + Struct(..) => { + let ordering = ordering_path(cx, if less ^ inclusive { "Less" } else { "Greater" }); + let comp_op = if inclusive { BinOpKind::Ne } else { BinOpKind::Eq }; + + cx.expr_binary(span, comp_op, fold, ordering) + } + _ => fold + } } diff --git a/src/test/compile-fail/derives-span-PartialOrd-enum-struct-variant.rs b/src/test/compile-fail/derives-span-PartialOrd-enum-struct-variant.rs index dcf02f30830..37e638c0553 100644 --- a/src/test/compile-fail/derives-span-PartialOrd-enum-struct-variant.rs +++ b/src/test/compile-fail/derives-span-PartialOrd-enum-struct-variant.rs @@ -18,9 +18,6 @@ enum Enum { A { x: Error //~ ERROR //~^ ERROR -//~^^ ERROR -//~^^^ ERROR -//~^^^^ ERROR } } diff --git a/src/test/compile-fail/derives-span-PartialOrd-enum.rs b/src/test/compile-fail/derives-span-PartialOrd-enum.rs index 7eb44c7e19e..da1281fc1c1 100644 --- a/src/test/compile-fail/derives-span-PartialOrd-enum.rs +++ b/src/test/compile-fail/derives-span-PartialOrd-enum.rs @@ -18,9 +18,6 @@ enum Enum { A( Error //~ ERROR //~^ ERROR -//~^^ ERROR -//~^^^ ERROR -//~^^^^ ERROR ) } diff --git a/src/test/compile-fail/derives-span-PartialOrd-struct.rs b/src/test/compile-fail/derives-span-PartialOrd-struct.rs index 36dae0124ce..fcc0593ab5e 100644 --- a/src/test/compile-fail/derives-span-PartialOrd-struct.rs +++ b/src/test/compile-fail/derives-span-PartialOrd-struct.rs @@ -17,9 +17,6 @@ struct Error; struct Struct { x: Error //~ ERROR //~^ ERROR -//~^^ ERROR -//~^^^ ERROR -//~^^^^ ERROR } fn main() {} diff --git a/src/test/compile-fail/derives-span-PartialOrd-tuple-struct.rs b/src/test/compile-fail/derives-span-PartialOrd-tuple-struct.rs index fd2df096754..24f75213e3f 100644 --- a/src/test/compile-fail/derives-span-PartialOrd-tuple-struct.rs +++ b/src/test/compile-fail/derives-span-PartialOrd-tuple-struct.rs @@ -17,9 +17,6 @@ struct Error; struct Struct( Error //~ ERROR //~^ ERROR -//~^^ ERROR -//~^^^ ERROR -//~^^^^ ERROR ); fn main() {} diff --git a/src/test/compile-fail/range_traits-1.rs b/src/test/compile-fail/range_traits-1.rs index df766e361d5..434ad3c4f07 100644 --- a/src/test/compile-fail/range_traits-1.rs +++ b/src/test/compile-fail/range_traits-1.rs @@ -15,35 +15,27 @@ struct AllTheRanges { a: Range, //~^ ERROR PartialOrd //~^^ ERROR Ord - //~^^^ ERROR binary operation `<` cannot be applied to type - //~^^^^ ERROR binary operation `>` cannot be applied to type + //~^^^ the trait bound b: RangeTo, //~^ ERROR PartialOrd //~^^ ERROR Ord - //~^^^ ERROR binary operation `<` cannot be applied to type - //~^^^^ ERROR binary operation `>` cannot be applied to type + //~^^^ no method named `partial_cmp` c: RangeFrom, //~^ ERROR PartialOrd //~^^ ERROR Ord - //~^^^ ERROR binary operation `<` cannot be applied to type - //~^^^^ ERROR binary operation `>` cannot be applied to type + //~^^^ the trait bound d: RangeFull, //~^ ERROR PartialOrd //~^^ ERROR Ord - //~^^^ ERROR binary operation `<` cannot be applied to type - //~^^^^ ERROR binary operation `>` cannot be applied to type + //~^^^ no method named `partial_cmp` e: RangeInclusive, //~^ ERROR PartialOrd //~^^ ERROR Ord - //~^^^ ERROR binary operation `<` cannot be applied to type - //~^^^^ ERROR binary operation `>` cannot be applied to type + //~^^^ the trait bound f: RangeToInclusive, //~^ ERROR PartialOrd //~^^ ERROR Ord - //~^^^ ERROR binary operation `<` cannot be applied to type - //~^^^^ ERROR binary operation `>` cannot be applied to type - //~^^^^^ ERROR binary operation `<=` cannot be applied to type - //~^^^^^^ ERROR binary operation `>=` cannot be applied to type + //~^^^ no method named `partial_cmp` } fn main() {} -- cgit 1.4.1-3-g733a5 From 6330bf24fe2641cec2045fdfaab439f96c35652a Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 17 Apr 2018 01:22:43 +0100 Subject: Fix handling of None --- src/libsyntax_ext/deriving/cmp/partial_ord.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs index b352e4b0a7e..b6f36582f3c 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs @@ -213,8 +213,8 @@ fn cs_op(less: bool, Ident::from_str("partial_cmp"), vec![cx.expr_addr_of(span, other_f.clone())]); - let default = ordering_path(cx, if less { "Greater" } else { "Less" }); - // `_.unwrap_or(Ordering::Greater/Less)` + let default = ordering_path(cx, "Equal"); + // `_.unwrap_or(Ordering::Equal)` cx.expr_method_call(span, cmp, Ident::from_str("unwrap_or"), vec![default]) }; @@ -225,8 +225,8 @@ fn cs_op(less: bool, // `ast::lt` // // ``` - // self.f1.partial_cmp(other.f1).unwrap_or(Ordering::Greater) - // .then_with(|| self.f2.partial_cmp(other.f2).unwrap_or(Ordering::Greater)) + // self.f1.partial_cmp(other.f1).unwrap_or(Ordering::Equal) + // .then_with(|| self.f2.partial_cmp(other.f2).unwrap_or(Ordering::Equal)) // == Ordering::Less // ``` // @@ -234,8 +234,8 @@ fn cs_op(less: bool, // `ast::le` // // ``` - // self.f1.partial_cmp(other.f1).unwrap_or(Ordering::Greater) - // .then_with(|| self.f2.partial_cmp(other.f2).unwrap_or(Ordering::Greater)) + // self.f1.partial_cmp(other.f1).unwrap_or(Ordering::Equal) + // .then_with(|| self.f2.partial_cmp(other.f2).unwrap_or(Ordering::Equal)) // != Ordering::Greater // ``` // @@ -243,10 +243,10 @@ fn cs_op(less: bool, // get use the binops to avoid auto-deref dereferencing too many // layers of pointers, if the type includes pointers. - // `self.fi.partial_cmp(other.fi).unwrap_or(Ordering::Greater/Less)` + // `self.fi.partial_cmp(other.fi).unwrap_or(Ordering::Equal)` let par_cmp = par_cmp(cx, span, self_f, other_fs); - // `self.fi.partial_cmp(other.fi).unwrap_or(Ordering::Greater/Less).then_with(...)` + // `self.fi.partial_cmp(other.fi).unwrap_or(Ordering::Equal).then_with(...)` cx.expr_method_call(span, par_cmp, Ident::from_str("then_with"), @@ -255,7 +255,7 @@ fn cs_op(less: bool, |cx, args| { match args { Some((span, self_f, other_fs)) => par_cmp(cx, span, self_f, other_fs), - None => ordering_path(cx, if less { "Less" } else { "Equal" }) + None => cx.expr_bool(span, inclusive) } }, Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| { @@ -276,8 +276,8 @@ fn cs_op(less: bool, substr); match *substr.fields { - EnumMatching(..) | - Struct(..) => { + EnumMatching(.., ref all_fields) | + Struct(.., ref all_fields) if !all_fields.is_empty() => { let ordering = ordering_path(cx, if less ^ inclusive { "Less" } else { "Greater" }); let comp_op = if inclusive { BinOpKind::Ne } else { BinOpKind::Eq }; -- cgit 1.4.1-3-g733a5 From 98e3e82ecea8b3b2100362e6fa87dc76779855bc Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 17 Apr 2018 19:52:58 +0100 Subject: Use UFCS --- src/etc/generate-deriving-span-tests.py | 2 +- src/libsyntax_ext/deriving/cmp/partial_ord.rs | 31 ++++++++++++++-------- .../derives-span-PartialOrd-enum-struct-variant.rs | 1 - .../compile-fail/derives-span-PartialOrd-enum.rs | 1 - .../compile-fail/derives-span-PartialOrd-struct.rs | 1 - .../derives-span-PartialOrd-tuple-struct.rs | 1 - src/test/compile-fail/range_traits-1.rs | 6 ----- 7 files changed, 21 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py index e248f471395..2e9169ce5b9 100755 --- a/src/etc/generate-deriving-span-tests.py +++ b/src/etc/generate-deriving-span-tests.py @@ -122,7 +122,7 @@ traits = { for (trait, supers, errs) in [('Clone', [], 1), ('PartialEq', [], 2), - ('PartialOrd', ['PartialEq'], 2), + ('PartialOrd', ['PartialEq'], 1), ('Eq', ['PartialEq'], 1), ('Ord', ['Eq', 'PartialOrd', 'PartialEq'], 1), ('Debug', [], 1), diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs index b6f36582f3c..f8c27bf42a9 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs @@ -201,21 +201,27 @@ fn cs_op(less: bool, cx.expr_path(cx.path_global(span, cx.std_path(&["cmp", "Ordering", name]))) }; - let par_cmp = |cx: &mut ExtCtxt, span: Span, self_f: P, other_fs: &[P]| { + let par_cmp = |cx: &mut ExtCtxt, span, self_f: P, other_fs: &[P], default| { let other_f = match (other_fs.len(), other_fs.get(0)) { (1, Some(o_f)) => o_f, _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`"), }; - // `self.fi.partial_cmp(other.fi)` - let cmp = cx.expr_method_call(span, - cx.expr_addr_of(span, self_f), - Ident::from_str("partial_cmp"), - vec![cx.expr_addr_of(span, other_f.clone())]); + // `PartialOrd::partial_cmp(self.fi, other.fi)` + let cmp_path = cx.expr_path(cx.path_global(span, cx.std_path(&["cmp", + "PartialOrd", + "partial_cmp"]))); + let cmp = cx.expr_call(span, + cmp_path, + vec![cx.expr_addr_of(span, self_f), + cx.expr_addr_of(span, other_f.clone())]); - let default = ordering_path(cx, "Equal"); - // `_.unwrap_or(Ordering::Equal)` - cx.expr_method_call(span, cmp, Ident::from_str("unwrap_or"), vec![default]) + let default = ordering_path(cx, default); + // `Option::unwrap_or(_, Ordering::Equal)` + let unwrap_path = cx.expr_path(cx.path_global(span, cx.std_path(&["option", + "Option", + "unwrap_or"]))); + cx.expr_call(span, unwrap_path, vec![cmp, default]) }; let fold = cs_fold1(false, // need foldr @@ -244,7 +250,7 @@ fn cs_op(less: bool, // layers of pointers, if the type includes pointers. // `self.fi.partial_cmp(other.fi).unwrap_or(Ordering::Equal)` - let par_cmp = par_cmp(cx, span, self_f, other_fs); + let par_cmp = par_cmp(cx, span, self_f, other_fs, "Equal"); // `self.fi.partial_cmp(other.fi).unwrap_or(Ordering::Equal).then_with(...)` cx.expr_method_call(span, @@ -254,7 +260,10 @@ fn cs_op(less: bool, }, |cx, args| { match args { - Some((span, self_f, other_fs)) => par_cmp(cx, span, self_f, other_fs), + Some((span, self_f, other_fs)) => { + let opposite = if less { "Greater" } else { "Less" }; + par_cmp(cx, span, self_f, other_fs, opposite) + }, None => cx.expr_bool(span, inclusive) } }, diff --git a/src/test/compile-fail/derives-span-PartialOrd-enum-struct-variant.rs b/src/test/compile-fail/derives-span-PartialOrd-enum-struct-variant.rs index 37e638c0553..a5df717e06b 100644 --- a/src/test/compile-fail/derives-span-PartialOrd-enum-struct-variant.rs +++ b/src/test/compile-fail/derives-span-PartialOrd-enum-struct-variant.rs @@ -17,7 +17,6 @@ struct Error; enum Enum { A { x: Error //~ ERROR -//~^ ERROR } } diff --git a/src/test/compile-fail/derives-span-PartialOrd-enum.rs b/src/test/compile-fail/derives-span-PartialOrd-enum.rs index da1281fc1c1..3411d2f3119 100644 --- a/src/test/compile-fail/derives-span-PartialOrd-enum.rs +++ b/src/test/compile-fail/derives-span-PartialOrd-enum.rs @@ -17,7 +17,6 @@ struct Error; enum Enum { A( Error //~ ERROR -//~^ ERROR ) } diff --git a/src/test/compile-fail/derives-span-PartialOrd-struct.rs b/src/test/compile-fail/derives-span-PartialOrd-struct.rs index fcc0593ab5e..1feadc2fd83 100644 --- a/src/test/compile-fail/derives-span-PartialOrd-struct.rs +++ b/src/test/compile-fail/derives-span-PartialOrd-struct.rs @@ -16,7 +16,6 @@ struct Error; #[derive(PartialOrd,PartialEq)] struct Struct { x: Error //~ ERROR -//~^ ERROR } fn main() {} diff --git a/src/test/compile-fail/derives-span-PartialOrd-tuple-struct.rs b/src/test/compile-fail/derives-span-PartialOrd-tuple-struct.rs index 24f75213e3f..9db0fed2d9e 100644 --- a/src/test/compile-fail/derives-span-PartialOrd-tuple-struct.rs +++ b/src/test/compile-fail/derives-span-PartialOrd-tuple-struct.rs @@ -16,7 +16,6 @@ struct Error; #[derive(PartialOrd,PartialEq)] struct Struct( Error //~ ERROR -//~^ ERROR ); fn main() {} diff --git a/src/test/compile-fail/range_traits-1.rs b/src/test/compile-fail/range_traits-1.rs index 434ad3c4f07..32f9b83b6e2 100644 --- a/src/test/compile-fail/range_traits-1.rs +++ b/src/test/compile-fail/range_traits-1.rs @@ -15,27 +15,21 @@ struct AllTheRanges { a: Range, //~^ ERROR PartialOrd //~^^ ERROR Ord - //~^^^ the trait bound b: RangeTo, //~^ ERROR PartialOrd //~^^ ERROR Ord - //~^^^ no method named `partial_cmp` c: RangeFrom, //~^ ERROR PartialOrd //~^^ ERROR Ord - //~^^^ the trait bound d: RangeFull, //~^ ERROR PartialOrd //~^^ ERROR Ord - //~^^^ no method named `partial_cmp` e: RangeInclusive, //~^ ERROR PartialOrd //~^^ ERROR Ord - //~^^^ the trait bound f: RangeToInclusive, //~^ ERROR PartialOrd //~^^ ERROR Ord - //~^^^ no method named `partial_cmp` } fn main() {} -- cgit 1.4.1-3-g733a5 From 6805e5abd2a6fbdca75ff3c96ee58398dcbdfd04 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 24 Apr 2018 21:56:57 +0100 Subject: Update comments to UFCS style --- src/libsyntax_ext/deriving/cmp/partial_ord.rs | 35 ++++++++++++++++++--------- 1 file changed, 24 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs index f8c27bf42a9..2b3930063f3 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs @@ -14,7 +14,7 @@ use deriving::{path_local, pathvec_std, path_std}; use deriving::generic::*; use deriving::generic::ty::*; -use syntax::ast::{self, BinOpKind, Expr, MetaItem, Ident}; +use syntax::ast::{self, BinOpKind, Expr, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; use syntax::ptr::P; @@ -231,8 +231,14 @@ fn cs_op(less: bool, // `ast::lt` // // ``` - // self.f1.partial_cmp(other.f1).unwrap_or(Ordering::Equal) - // .then_with(|| self.f2.partial_cmp(other.f2).unwrap_or(Ordering::Equal)) + // Ordering::then_with( + // Option::unwrap_or( + // PartialOrd::partial_cmp(self.f1, other.f1), Ordering::Equal) + // ), + // Option::unwrap_or( + // PartialOrd::partial_cmp(self.f2, other.f2), Ordering::Greater) + // ) + // ) // == Ordering::Less // ``` // @@ -240,8 +246,14 @@ fn cs_op(less: bool, // `ast::le` // // ``` - // self.f1.partial_cmp(other.f1).unwrap_or(Ordering::Equal) - // .then_with(|| self.f2.partial_cmp(other.f2).unwrap_or(Ordering::Equal)) + // Ordering::then_with( + // Option::unwrap_or( + // PartialOrd::partial_cmp(self.f1, other.f1), Ordering::Equal) + // ), + // Option::unwrap_or( + // PartialOrd::partial_cmp(self.f2, other.f2), Ordering::Greater) + // ) + // ) // != Ordering::Greater // ``` // @@ -249,14 +261,15 @@ fn cs_op(less: bool, // get use the binops to avoid auto-deref dereferencing too many // layers of pointers, if the type includes pointers. - // `self.fi.partial_cmp(other.fi).unwrap_or(Ordering::Equal)` + // `Option::unwrap_or(PartialOrd::partial_cmp(self.fi, other.fi), Ordering::Equal)` let par_cmp = par_cmp(cx, span, self_f, other_fs, "Equal"); - // `self.fi.partial_cmp(other.fi).unwrap_or(Ordering::Equal).then_with(...)` - cx.expr_method_call(span, - par_cmp, - Ident::from_str("then_with"), - vec![cx.lambda0(span, subexpr)]) + // `Ordering::then_with(Option::unwrap_or(..), ..)` + let then_with_path = cx.expr_path(cx.path_global(span, + cx.std_path(&["cmp", + "Ordering", + "then_with"]))); + cx.expr_call(span, then_with_path, vec![par_cmp, cx.lambda0(span, subexpr)]) }, |cx, args| { match args { -- cgit 1.4.1-3-g733a5 From 9b2890196eba62fdfec09447305e197642d1c612 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 30 Apr 2018 22:43:33 +0100 Subject: Remove vestigial diverging !-coercion Such conversions are no longer permitted. --- src/librustc_typeck/check/_match.rs | 2 +- src/librustc_typeck/check/coercion.rs | 24 +++++------------------- src/librustc_typeck/check/mod.rs | 32 ++++++++++---------------------- 3 files changed, 16 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 7b4dc60409b..6a76e170a62 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -690,7 +690,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); arm_span: arm.body.span, source: match_src }); - coercion.coerce(self, &cause, &arm.body, arm_ty, self.diverges.get()); + coercion.coerce(self, &cause, &arm.body, arm_ty); } } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 8c69608a261..770a44a9b8b 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -60,7 +60,7 @@ //! sort of a minor point so I've opted to leave it for later---after all //! we may want to adjust precisely when coercions occur. -use check::{Diverges, FnCtxt, Needs}; +use check::{FnCtxt, Needs}; use rustc::hir; use rustc::hir::def_id::DefId; @@ -798,8 +798,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { exprs: &[E], prev_ty: Ty<'tcx>, new: &hir::Expr, - new_ty: Ty<'tcx>, - new_diverges: Diverges) + new_ty: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> where E: AsCoercionSite { @@ -807,13 +806,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let new_ty = self.resolve_type_vars_with_obligations(new_ty); debug!("coercion::try_find_coercion_lub({:?}, {:?})", prev_ty, new_ty); - // Special-ish case: we can coerce any type `T` into the `!` - // type, but only if the source expression diverges. - if prev_ty.is_never() && new_diverges.always() { - debug!("permit coercion to `!` because expr diverges"); - return Ok(prev_ty); - } - // Special-case that coercion alone cannot handle: // Two function item types of differing IDs or Substs. if let (&ty::TyFnDef(..), &ty::TyFnDef(..)) = (&prev_ty.sty, &new_ty.sty) { @@ -1052,14 +1044,12 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> fcx: &FnCtxt<'a, 'gcx, 'tcx>, cause: &ObligationCause<'tcx>, expression: &'gcx hir::Expr, - expression_ty: Ty<'tcx>, - expression_diverges: Diverges) + expression_ty: Ty<'tcx>) { self.coerce_inner(fcx, cause, Some(expression), expression_ty, - expression_diverges, None, false) } @@ -1085,7 +1075,6 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> cause, None, fcx.tcx.mk_nil(), - Diverges::Maybe, Some(augment_error), label_unit_as_expected) } @@ -1098,7 +1087,6 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> cause: &ObligationCause<'tcx>, expression: Option<&'gcx hir::Expr>, mut expression_ty: Ty<'tcx>, - expression_diverges: Diverges, augment_error: Option<&mut FnMut(&mut DiagnosticBuilder)>, label_expression_as_expected: bool) { @@ -1132,15 +1120,13 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> exprs, self.merged_ty(), expression, - expression_ty, - expression_diverges), + expression_ty), Expressions::UpFront(ref coercion_sites) => fcx.try_find_coercion_lub(cause, &coercion_sites[0..self.pushed], self.merged_ty(), expression, - expression_ty, - expression_diverges), + expression_ty), } } } else { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index db859e42057..9c73e5a8ce7 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -542,7 +542,7 @@ pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { /// you get indicates whether any subexpression that was /// evaluating up to and including `X` diverged. /// - /// We use this flag for two purposes: + /// We currently use this flag only for diagnostic purposes: /// /// - To warn about unreachable code: if, after processing a /// sub-expression but before we have applied the effects of the @@ -556,16 +556,8 @@ pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { /// foo();}` or `{return; 22}`, where we would warn on the /// `foo()` or `22`. /// - /// - To permit assignment into a local variable or other place - /// (including the "return slot") of type `!`. This is allowed - /// if **either** the type of value being assigned is `!`, which - /// means the current code is dead, **or** the expression's - /// diverging flag is true, which means that a diverging value was - /// wrapped (e.g., `let x: ! = foo(return)`). - /// - /// To repeat the last point: an expression represents dead-code - /// if, after checking it, **either** its type is `!` OR the - /// diverges flag is set to something other than `Maybe`. + /// An expression represents dead-code if, after checking it, + /// the diverges flag is set to something other than `Maybe`. diverges: Cell, /// Whether any child nodes have any type errors. @@ -2999,8 +2991,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { &self.cause(return_expr.span, ObligationCauseCode::ReturnType(return_expr.id)), return_expr, - return_expr_ty, - self.diverges.get()); + return_expr_ty); } @@ -3031,13 +3022,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let mut coerce: DynamicCoerceMany = CoerceMany::new(coerce_to_ty); let if_cause = self.cause(sp, ObligationCauseCode::IfExpression); - coerce.coerce(self, &if_cause, then_expr, then_ty, then_diverges); + coerce.coerce(self, &if_cause, then_expr, then_ty); if let Some(else_expr) = opt_else_expr { let else_ty = self.check_expr_with_expectation(else_expr, expected); let else_diverges = self.diverges.get(); - coerce.coerce(self, &if_cause, else_expr, else_ty, else_diverges); + coerce.coerce(self, &if_cause, else_expr, else_ty); // We won't diverge unless both branches do (or the condition does). self.diverges.set(cond_diverges | then_diverges & else_diverges); @@ -3722,7 +3713,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } hir::ExprBreak(destination, ref expr_opt) => { if let Some(target_id) = destination.target_id.opt_id() { - let (e_ty, e_diverges, cause); + let (e_ty, cause); if let Some(ref e) = *expr_opt { // If this is a break with a value, we need to type-check // the expression. Get an expected type from the loop context. @@ -3741,13 +3732,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Recurse without `enclosing_breakables` borrowed. e_ty = self.check_expr_with_hint(e, coerce_to); - e_diverges = self.diverges.get(); cause = self.misc(e.span); } else { // Otherwise, this is a break *without* a value. That's // always legal, and is equivalent to `break ()`. e_ty = tcx.mk_nil(); - e_diverges = Diverges::Maybe; cause = self.misc(expr.span); } @@ -3758,7 +3747,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let ctxt = enclosing_breakables.find_breakable(target_id); if let Some(ref mut coerce) = ctxt.coerce { if let Some(ref e) = *expr_opt { - coerce.coerce(self, &cause, e, e_ty, e_diverges); + coerce.coerce(self, &cause, e, e_ty); } else { assert!(e_ty.is_nil()); coerce.coerce_forced_unit(self, &cause, &mut |_| (), true); @@ -3964,7 +3953,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { for e in args { let e_ty = self.check_expr_with_hint(e, coerce_to); let cause = self.misc(e.span); - coerce.coerce(self, &cause, e, e_ty, self.diverges.get()); + coerce.coerce(self, &cause, e, e_ty); } coerce.complete(self) } else { @@ -4375,8 +4364,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { coerce.coerce(self, &cause, tail_expr, - tail_expr_ty, - self.diverges.get()); + tail_expr_ty); } else { // Subtle: if there is no explicit tail expression, // that is typically equivalent to a tail expression -- cgit 1.4.1-3-g733a5 From 5a013b2fbcd2eebc8345ccd1611e39b867b4c1f8 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 1 May 2018 00:23:34 +0100 Subject: Fix coerce-to-bang test This was explicitly testing the behaviour which is now no longer permitted. --- src/test/compile-fail/coerce-to-bang.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/test/compile-fail/coerce-to-bang.rs b/src/test/compile-fail/coerce-to-bang.rs index 62ff09f4616..4a0e31d2deb 100644 --- a/src/test/compile-fail/coerce-to-bang.rs +++ b/src/test/compile-fail/coerce-to-bang.rs @@ -56,9 +56,8 @@ fn call_foo_f() { } fn array_a() { - // Accepted: return is coerced to `!` just fine, and then `22` can be - // because we already diverged. - let x: [!; 2] = [return, 22]; + // Accepted: return is coerced to `!` just fine, but `22` cannot be. + let x: [!; 2] = [return, 22]; //~ ERROR mismatched types } fn array_b() { -- cgit 1.4.1-3-g733a5 From 5489969fa18cc74d4b72077940a5c05491ec681f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 1 May 2018 12:27:09 -0400 Subject: Test is no longer "accepted" --- src/test/compile-fail/coerce-to-bang.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/test/compile-fail/coerce-to-bang.rs b/src/test/compile-fail/coerce-to-bang.rs index 4a0e31d2deb..8b4e2c3c051 100644 --- a/src/test/compile-fail/coerce-to-bang.rs +++ b/src/test/compile-fail/coerce-to-bang.rs @@ -56,7 +56,7 @@ fn call_foo_f() { } fn array_a() { - // Accepted: return is coerced to `!` just fine, but `22` cannot be. + // Return is coerced to `!` just fine, but `22` cannot be. let x: [!; 2] = [return, 22]; //~ ERROR mismatched types } -- cgit 1.4.1-3-g733a5 From cf9209f87274548f25e01621a712afcb036ede6e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 26 Apr 2018 00:36:00 +0200 Subject: Improve results --- src/librustdoc/html/static/main.js | 75 ++++++++++++++++++++++------------ src/librustdoc/html/static/rustdoc.css | 4 ++ 2 files changed, 53 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 8569abeb09c..ba92ac7bd30 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -454,12 +454,16 @@ var obj = searchIndex[results[i].id]; obj.lev = results[i].lev; if (isType !== true || obj.type) { + var res = buildHrefAndPath(obj); + obj.displayPath = pathSplitter(res[0]); + obj.fullPath = obj.displayPath + obj.name; + obj.href = res[1]; out.push(obj); + if (out.length >= MAX_RESULTS) { + break; + } } } - if (out.length >= MAX_RESULTS) { - break; - } } return out; } @@ -1017,6 +1021,12 @@ ALIASES[window.currentCrate][query.raw]) { var aliases = ALIASES[window.currentCrate][query.raw]; for (var i = 0; i < aliases.length; ++i) { + aliases[i].is_alias = true; + aliases[i].alias = query.raw; + var res = buildHrefAndPath(aliases[i]); + aliases[i].displayPath = pathSplitter(res[0]); + aliases[i].fullPath = aliases[i].displayPath + aliases[i].name; + aliases[i].href = res[1]; ret['others'].unshift(aliases[i]); if (ret['others'].length > MAX_RESULTS) { ret['others'].pop(); @@ -1179,16 +1189,6 @@ }; } - function escape(content) { - var h1 = document.createElement('h1'); - h1.textContent = content; - return h1.innerHTML; - } - - function pathSplitter(path) { - return '' + path.replace(/::/g, '::'); - } - function buildHrefAndPath(item) { var displayPath; var href; @@ -1227,6 +1227,16 @@ return [displayPath, href]; } + function escape(content) { + var h1 = document.createElement('h1'); + h1.textContent = content; + return h1.innerHTML; + } + + function pathSplitter(path) { + return '' + path.replace(/::/g, '::'); + } + function addTab(array, query, display) { var extraStyle = ''; if (display === false) { @@ -1234,12 +1244,13 @@ } var output = ''; + var duplicates = {}; if (array.length > 0) { output = ''; var shown = []; array.forEach(function(item) { - var name, type, href, displayPath; + var name, type; var id_ty = item.ty + item.path + item.name; if (shown.indexOf(id_ty) !== -1) { @@ -1250,15 +1261,23 @@ name = item.name; type = itemTypes[item.ty]; - var res = buildHrefAndPath(item); - var href = res[1]; - var displayPath = res[0]; + if (item.is_alias !== true) { + var fullPath = item.displayPath + name; + + if (duplicates[fullPath]) { + return; + } + duplicates[fullPath] = true; + } output += ''; }); @@ -1284,8 +1303,7 @@ if (results['others'].length === 1 && getCurrentValue('rustdoc-go-to-only-result') === "true") { var elem = document.createElement('a'); - var res = buildHrefAndPath(results['others'][0]); - elem.href = res[1]; + elem.href = results['others'][0].href; elem.style.display = 'none'; // For firefox, we need the element to be in the DOM so it can be clicked. document.body.appendChild(elem); @@ -1347,12 +1365,13 @@ } } if (queries.length > 1) { - function getSmallest(arrays, positions) { + function getSmallest(arrays, positions, notDuplicates) { var start = null; for (var it = 0; it < positions.length; ++it) { if (arrays[it].length > positions[it] && - (start === null || start > arrays[it][positions[it]].lev)) { + (start === null || start > arrays[it][positions[it]].lev) && + !notDuplicates[arrays[it][positions[it]].fullPath]) { start = arrays[it][positions[it]].lev; } } @@ -1362,19 +1381,23 @@ function mergeArrays(arrays) { var ret = []; var positions = []; + var notDuplicates = {}; for (var x = 0; x < arrays.length; ++x) { positions.push(0); } while (ret.length < MAX_RESULTS) { - var smallest = getSmallest(arrays, positions); + var smallest = getSmallest(arrays, positions, notDuplicates); + if (smallest === null) { break; } for (x = 0; x < arrays.length && ret.length < MAX_RESULTS; ++x) { if (arrays[x].length > positions[x] && - arrays[x][positions[x]].lev === smallest) { + arrays[x][positions[x]].lev === smallest && + !notDuplicates[arrays[x][positions[x]].fullPath]) { ret.push(arrays[x][positions[x]]); + notDuplicates[arrays[x][positions[x]].fullPath] = true; positions[x] += 1; } } diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index d6b3ab26af8..08df4adf57d 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1326,4 +1326,8 @@ kbd { } #all-types > p { margin: 5px 0; +} + +.search-results td span.grey { + color: #ccc; } \ No newline at end of file -- cgit 1.4.1-3-g733a5 From e81b59bba88d216dcbc7bdf3f6aef8098fe3a7d7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 26 Apr 2018 21:14:10 +0200 Subject: Improve alias rendering --- src/librustdoc/html/static/main.js | 2 +- src/librustdoc/html/static/rustdoc.css | 4 ---- src/librustdoc/html/static/themes/dark.css | 9 ++++++++- src/librustdoc/html/static/themes/light.css | 7 +++++++ 4 files changed, 16 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index ba92ac7bd30..8c4dac9238c 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1273,7 +1273,7 @@ output += '
' + - '' + - pathSplitter(displayPath) + '' + + '' + + (item.is_alias === true ? + ('' + item.alias + '  - see ') : '') + + item.displayPath + '' + name + '' + - '' + + '' + '' + escape(item.desc) + ' 
' + '' + (item.is_alias === true ? - ('' + item.alias + ' ' + item.alias + '  - see ') : '') + item.displayPath + '' + name + '' + diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 08df4adf57d..d6b3ab26af8 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1326,8 +1326,4 @@ kbd { } #all-types > p { margin: 5px 0; -} - -.search-results td span.grey { - color: #ccc; } \ No newline at end of file diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index da4be7db5aa..493a75e2521 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -382,7 +382,7 @@ kbd { } #theme-choices > button:hover, #theme-choices > button:focus { - background-color: #444; + background-color: #4e4e4e; } @media (max-width: 700px) { @@ -397,3 +397,10 @@ kbd { #all-types:hover { background-color: #606060; } + +.search-results td span.alias { + color: #fff; +} +.search-results td span.grey { + color: #ccc; +} \ No newline at end of file diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 12af01d2e24..22f4635fb02 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -390,4 +390,11 @@ kbd { } #all-types:hover { background-color: #f9f9f9; +} + +.search-results td span.alias { + color: #000; +} +.search-results td span.grey { + color: #999; } \ No newline at end of file -- cgit 1.4.1-3-g733a5 From 8c80124fef9c2d9afceafc4f154b98390974670a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 26 Apr 2018 22:27:12 +0200 Subject: Add missing description in alias items --- src/librustdoc/html/render.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 21de2db1dfe..7fff981d090 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -879,8 +879,8 @@ themePicker.onclick = function() {{ } fn show_item(item: &IndexItem, krate: &str) -> String { - format!("{{'crate':'{}','ty':{},'name':'{}','path':'{}'{}}}", - krate, item.ty as usize, item.name, item.path, + format!("{{'crate':'{}','ty':{},'name':'{}','desc':'{}','path':'{}'{}}}", + krate, item.ty as usize, item.name, item.desc, item.path, if let Some(p) = item.parent_idx { format!(",'parent':{}", p) } else { @@ -1442,7 +1442,7 @@ impl<'a> Cache { ty: item.type_(), name: item_name.to_string(), path: path.clone(), - desc: String::new(), + desc: plain_summary_line(item.doc_value()), parent: None, parent_idx: None, search_type: get_index_search_type(&item), -- cgit 1.4.1-3-g733a5 From 9483e9b56474788e6549a1922e57f4a65c1c0bb0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 26 Apr 2018 23:44:25 +0200 Subject: Handle blur on theme buttons nicely --- src/librustdoc/html/render.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 7fff981d090..d6ea9b00a48 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -789,7 +789,8 @@ fn write_shared(cx: &Context, format!( r#"var themes = document.getElementById("theme-choices"); var themePicker = document.getElementById("theme-picker"); -themePicker.onclick = function() {{ + +function switchThemeButtonState() {{ if (themes.style.display === "block") {{ themes.style.display = "none"; themePicker.style.borderBottomRightRadius = "3px"; @@ -800,12 +801,29 @@ themePicker.onclick = function() {{ themePicker.style.borderBottomLeftRadius = "0"; }} }}; + +function handleThemeButtonsBlur(e) {{ + var active = document.activeElement; + var related = e.relatedTarget; + + if (active.id !== "themePicker" && + (!active.parentNode || active.parentNode.id !== "theme-choices") && + (!related || + (related.id !== "themePicker" && + (!related.parentNode || related.parentNode.id !== "theme-choices")))) {{ + switchThemeButtonState(); + }} +}} + +themePicker.onclick = switchThemeButtonState; +themePicker.onblur = handleThemeButtonsBlur; [{}].forEach(function(item) {{ var but = document.createElement('button'); but.innerHTML = item; but.onclick = function(el) {{ switchTheme(currentTheme, mainTheme, item); }}; + but.onblur = handleThemeButtonsBlur; themes.appendChild(but); }});"#, themes.iter() -- cgit 1.4.1-3-g733a5 From 72b7c8d2912b062e421bf17a584835e2ac66c124 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 5 May 2018 16:36:49 +0200 Subject: Remove extra span tags --- src/librustdoc/html/static/main.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 8c4dac9238c..b8d861d376f 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -57,6 +57,12 @@ return this.indexOf(searchString, position) === position; }; } + if (!String.prototype.endsWith) { + String.prototype.endsWith = function(suffix, length) { + var l = length || this.length; + return this.indexOf(suffix, l - suffix.length) !== -1; + }; + } function getPageId() { var id = document.location.href.split('#')[1]; @@ -1234,7 +1240,11 @@ } function pathSplitter(path) { - return '' + path.replace(/::/g, '::'); + var tmp = '' + path.replace(/::/g, '::'); + if (tmp.endsWith("")) { + return tmp.slice(0, tmp.length - 6); + } + return tmp; } function addTab(array, query, display) { -- cgit 1.4.1-3-g733a5 From 6a4bdda87bc09ba080f42ffe30cb488b3740ca9e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 5 May 2018 17:06:08 +0200 Subject: Reduce js files size --- src/librustdoc/html/render.rs | 16 +++++++++------ src/librustdoc/html/static/main.js | 41 +++++++++++++++++++------------------- 2 files changed, 31 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index d6ea9b00a48..7bddeb2f33f 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -413,9 +413,9 @@ impl ToJson for Type { match self.name { Some(ref name) => { let mut data = BTreeMap::new(); - data.insert("name".to_owned(), name.to_json()); + data.insert("n".to_owned(), name.to_json()); if let Some(ref generics) = self.generics { - data.insert("generics".to_owned(), generics.to_json()); + data.insert("g".to_owned(), generics.to_json()); } Json::Object(data) }, @@ -438,8 +438,12 @@ impl ToJson for IndexItemFunctionType { Json::Null } else { let mut data = BTreeMap::new(); - data.insert("inputs".to_owned(), self.inputs.to_json()); - data.insert("output".to_owned(), self.output.to_json()); + if !self.inputs.is_empty() { + data.insert("i".to_owned(), self.inputs.to_json()); + } + if let Some(ref output) = self.output { + data.insert("o".to_owned(), output.to_json()); + } Json::Object(data) } } @@ -897,8 +901,8 @@ themePicker.onblur = handleThemeButtonsBlur; } fn show_item(item: &IndexItem, krate: &str) -> String { - format!("{{'crate':'{}','ty':{},'name':'{}','desc':'{}','path':'{}'{}}}", - krate, item.ty as usize, item.name, item.desc, item.path, + format!("{{'crate':'{}','ty':{},'name':'{}','desc':'{}','p':'{}'{}}}", + krate, item.ty as usize, item.name, item.desc.replace("'", "\\'"), item.path, if let Some(p) = item.parent_idx { format!(",'parent':{}", p) } else { diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index b8d861d376f..527c880b34f 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -462,7 +462,7 @@ if (isType !== true || obj.type) { var res = buildHrefAndPath(obj); obj.displayPath = pathSplitter(res[0]); - obj.fullPath = obj.displayPath + obj.name; + obj.fullPath = obj.displayPath + obj.n; obj.href = res[1]; out.push(obj); if (out.length >= MAX_RESULTS) { @@ -597,8 +597,8 @@ // match as well. var lev_distance = MAX_LEV_DISTANCE + 1; if (val.generics.length > 0) { - if (obj.generics && obj.generics.length >= val.generics.length) { - var elems = obj.generics.slice(0); + if (obj.g && obj.g.length >= val.generics.length) { + var elems = obj.g.slice(0); var total = 0; var done = 0; // We need to find the type that matches the most to remove it in order @@ -630,11 +630,11 @@ // Check for type name and type generics (if any). function checkType(obj, val, literalSearch) { var lev_distance = MAX_LEV_DISTANCE + 1; - if (obj.name === val.name) { + if (obj.n === val.name) { if (literalSearch === true) { if (val.generics && val.generics.length !== 0) { - if (obj.generics && obj.length >= val.generics.length) { - var elems = obj.generics.slice(0); + if (obj.g && obj.length >= val.generics.length) { + var elems = obj.g.slice(0); var allFound = true; var x; @@ -658,7 +658,7 @@ } // If the type has generics but don't match, then it won't return at this point. // Otherwise, `checkGenerics` will return 0 and it'll return. - if (obj.generics && obj.generics.length !== 0) { + if (obj.g && obj.g.length !== 0) { var tmp_lev = checkGenerics(obj, val); if (tmp_lev <= MAX_LEV_DISTANCE) { return tmp_lev; @@ -669,22 +669,22 @@ } // Names didn't match so let's check if one of the generic types could. if (literalSearch === true) { - if (obj.generics && obj.generics.length > 0) { - for (var x = 0; x < obj.generics.length; ++x) { - if (obj.generics[x] === val.name) { + if (obj.g && obj.g.length > 0) { + for (var x = 0; x < obj.g.length; ++x) { + if (obj.g[x] === val.name) { return true; } } } return false; } - var lev_distance = Math.min(levenshtein(obj.name, val.name), lev_distance); + var lev_distance = Math.min(levenshtein(obj.n, val.name), lev_distance); if (lev_distance <= MAX_LEV_DISTANCE) { lev_distance = Math.min(checkGenerics(obj, val), lev_distance); - } else if (obj.generics && obj.generics.length > 0) { + } else if (obj.g && obj.g.length > 0) { // We can check if the type we're looking for is inside the generics! - for (var x = 0; x < obj.generics.length; ++x) { - lev_distance = Math.min(levenshtein(obj.generics[x], val.name), + for (var x = 0; x < obj.g.length; ++x) { + lev_distance = Math.min(levenshtein(obj.g[x], val.name), lev_distance); } } @@ -696,9 +696,9 @@ function findArg(obj, val, literalSearch) { var lev_distance = MAX_LEV_DISTANCE + 1; - if (obj && obj.type && obj.type.inputs.length > 0) { - for (var i = 0; i < obj.type.inputs.length; i++) { - var tmp = checkType(obj.type.inputs[i], val, literalSearch); + if (obj && obj.type && obj.type.i && obj.type.i.length > 0) { + for (var i = 0; i < obj.type.i.length; i++) { + var tmp = checkType(obj.type.i[i], val, literalSearch); if (literalSearch === true && tmp === true) { return true; } @@ -714,8 +714,8 @@ function checkReturned(obj, val, literalSearch) { var lev_distance = MAX_LEV_DISTANCE + 1; - if (obj && obj.type && obj.type.output) { - var tmp = checkType(obj.type.output, val, literalSearch); + if (obj && obj.type && obj.type.o) { + var tmp = checkType(obj.type.o, val, literalSearch); if (literalSearch === true && tmp === true) { return true; } @@ -860,7 +860,7 @@ var fullId = generateId(ty); // allow searching for void (no output) functions as well - var typeOutput = type.output ? type.output.name : ""; + var typeOutput = type.o ? type.o.name : ""; var returned = checkReturned(ty, output, true); if (output.name === "*" || returned === true) { var in_args = false; @@ -1029,6 +1029,7 @@ for (var i = 0; i < aliases.length; ++i) { aliases[i].is_alias = true; aliases[i].alias = query.raw; + aliases[i].path = aliases[i].p; var res = buildHrefAndPath(aliases[i]); aliases[i].displayPath = pathSplitter(res[0]); aliases[i].fullPath = aliases[i].displayPath + aliases[i].name; -- cgit 1.4.1-3-g733a5 From 8fab482a68310da88ae72c1aef6edb19067949f1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 12 May 2018 13:52:25 +0200 Subject: Fix items counts in search results --- src/librustdoc/html/static/main.js | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 527c880b34f..e08f3261871 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1256,6 +1256,7 @@ var output = ''; var duplicates = {}; + var length = 0; if (array.length > 0) { output = ''; var shown = []; @@ -1280,6 +1281,7 @@ } duplicates[fullPath] = true; } + length += 1; output += '
' + '' + @@ -1299,7 +1301,7 @@ encodeURIComponent('rust ' + query.query) + '">DuckDuckGo?'; } - return output; + return [output, length]; } function makeTabHeader(tabNb, text, nbElems) { @@ -1320,21 +1322,22 @@ document.body.appendChild(elem); elem.click(); } - var output, query = getQuery(search_input.value); + var query = getQuery(search_input.value); currentResults = query.id; - output = '

Results for ' + escape(query.query) + + + var ret_others = addTab(results['others'], query); + var ret_in_args = addTab(results['in_args'], query, false); + var ret_returned = addTab(results['returned'], query, false); + + var output = '

Results for ' + escape(query.query) + (query.type ? ' (type: ' + escape(query.type) + ')' : '') + '

' + '
' + - makeTabHeader(0, "In Names", results['others'].length) + - makeTabHeader(1, "In Parameters", results['in_args'].length) + - makeTabHeader(2, "In Return Types", results['returned'].length) + - '
'; - - output += addTab(results['others'], query); - output += addTab(results['in_args'], query, false); - output += addTab(results['returned'], query, false); - output += '
'; + makeTabHeader(0, "In Names", ret_others[1]) + + makeTabHeader(1, "In Parameters", ret_in_args[1]) + + makeTabHeader(2, "In Return Types", ret_returned[1]) + + '
' + + ret_others[0] + ret_in_args[0] + ret_returned[0] + '
'; addClass(document.getElementById('main'), 'hidden'); var search = document.getElementById('search'); -- cgit 1.4.1-3-g733a5 From f2bc09e68bfc5d84a7abf49bedb5ced8f99b95a7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 12 May 2018 14:57:52 +0200 Subject: Fix invalid deduplication --- src/librustdoc/html/static/main.js | 9 +-------- src/test/rustdoc-js/deduplication.js | 21 +++++++++++++++++++++ src/tools/rustdoc-js/tester.js | 5 +++-- 3 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 src/test/rustdoc-js/deduplication.js (limited to 'src') diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index e08f3261871..3ee06a964de 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -462,7 +462,7 @@ if (isType !== true || obj.type) { var res = buildHrefAndPath(obj); obj.displayPath = pathSplitter(res[0]); - obj.fullPath = obj.displayPath + obj.n; + obj.fullPath = obj.displayPath + obj.name; obj.href = res[1]; out.push(obj); if (out.length >= MAX_RESULTS) { @@ -1259,17 +1259,10 @@ var length = 0; if (array.length > 0) { output = ''; - var shown = []; array.forEach(function(item) { var name, type; - var id_ty = item.ty + item.path + item.name; - if (shown.indexOf(id_ty) !== -1) { - return; - } - - shown.push(id_ty); name = item.name; type = itemTypes[item.ty]; diff --git a/src/test/rustdoc-js/deduplication.js b/src/test/rustdoc-js/deduplication.js new file mode 100644 index 00000000000..0f29607d5c9 --- /dev/null +++ b/src/test/rustdoc-js/deduplication.js @@ -0,0 +1,21 @@ +// Copyright 2018 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. + +// ignore-order + +const QUERY = 'is_nan'; + +const EXPECTED = { + 'others': [ + { 'path': 'std::f32', 'name': 'is_nan' }, + { 'path': 'std::f64', 'name': 'is_nan' }, + { 'path': 'std::option::Option', 'name': 'is_none' }, + ], +}; diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 25f7a2d1294..47667d93cb7 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -160,10 +160,11 @@ function main(argv) { // execQuery first parameter is built in getQuery (which takes in the search input). // execQuery last parameter is built in buildIndex. // buildIndex requires the hashmap from search-index. - var functionsToLoad = ["levenshtein", "validateResult", "getQuery", "buildIndex", "execQuery", - "execSearch"]; + var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult", + "getQuery", "buildIndex", "execQuery", "execSearch"]; finalJS += 'window = { "currentCrate": "std" };\n'; + finalJS += 'var rootPath = "../";\n'; finalJS += ALIASES; finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs); finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs); -- cgit 1.4.1-3-g733a5 From f0db2cf14e8b58eb04d40e8aebea0a7a987097eb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 12 May 2018 23:44:40 +0200 Subject: Use fullpath instead of recreating it --- src/librustdoc/html/static/main.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 3ee06a964de..9224bd1c508 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1267,12 +1267,10 @@ type = itemTypes[item.ty]; if (item.is_alias !== true) { - var fullPath = item.displayPath + name; - - if (duplicates[fullPath]) { + if (duplicates[item.fullPath]) { return; } - duplicates[fullPath] = true; + duplicates[item.fullPath] = true; } length += 1; -- cgit 1.4.1-3-g733a5 From e0567158dd3a1421fe55e27bee4ffb885ea3f149 Mon Sep 17 00:00:00 2001 From: Sébastien Marie Date: Sun, 13 May 2018 07:14:36 +0200 Subject: update libcompiler_builtins let's OpenBSD to use libcompiler_rt.a from system library. it unbreaks the build from source on OpenBSD. --- src/libcompiler_builtins | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins index 2a2f6d96c8d..4cfd7101eb5 160000 --- a/src/libcompiler_builtins +++ b/src/libcompiler_builtins @@ -1 +1 @@ -Subproject commit 2a2f6d96c8dc578d2474742f14c9bab0b36b0408 +Subproject commit 4cfd7101eb549169cdaeda5313f7c39415b9d736 -- cgit 1.4.1-3-g733a5 From b638f11b4230ad2e098a75474c36a10de1653d0d Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Fri, 11 May 2018 11:26:51 +0200 Subject: Introduce OperandValue::volatile_store and use it in the intrinsics Fixes #50371. --- src/librustc_trans/abi.rs | 3 ++- src/librustc_trans/base.rs | 10 ++++++---- src/librustc_trans/builder.rs | 3 ++- src/librustc_trans/intrinsic.rs | 21 +++------------------ src/librustc_trans/mir/block.rs | 2 +- src/librustc_trans/mir/operand.rs | 24 +++++++++++++++++++++--- 6 files changed, 35 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 1838dae049a..c80d989e3cb 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -220,7 +220,8 @@ impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> { bx.pointercast(dst.llval, Type::i8p(cx)), bx.pointercast(llscratch, Type::i8p(cx)), C_usize(cx, self.layout.size.bytes()), - self.layout.align.min(scratch_align)); + self.layout.align.min(scratch_align), + false); bx.lifetime_end(llscratch, scratch_size); } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 0dd1adbff86..65dce5f3ffb 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -320,7 +320,7 @@ pub fn coerce_unsized_into<'a, 'tcx>(bx: &Builder<'a, 'tcx>, if src_f.layout.ty == dst_f.layout.ty { memcpy_ty(bx, dst_f.llval, src_f.llval, src_f.layout, - src_f.align.min(dst_f.align)); + src_f.align.min(dst_f.align), false); } else { coerce_unsized_into(bx, src_f, dst_f); } @@ -408,7 +408,8 @@ pub fn call_memcpy(bx: &Builder, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, - align: Align) { + align: Align, + volatile: bool) { let cx = bx.cx; let ptr_width = &cx.sess().target.target.target_pointer_width; let key = format!("llvm.memcpy.p0i8.p0i8.i{}", ptr_width); @@ -417,7 +418,7 @@ pub fn call_memcpy(bx: &Builder, let dst_ptr = bx.pointercast(dst, Type::i8p(cx)); let size = bx.intcast(n_bytes, cx.isize_ty, false); let align = C_i32(cx, align.abi() as i32); - let volatile = C_bool(cx, false); + let volatile = C_bool(cx, volatile); bx.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None); } @@ -427,13 +428,14 @@ pub fn memcpy_ty<'a, 'tcx>( src: ValueRef, layout: TyLayout<'tcx>, align: Align, + volatile: bool, ) { let size = layout.size.bytes(); if size == 0 { return; } - call_memcpy(bx, dst, src, C_usize(bx.cx, size), align); + call_memcpy(bx, dst, src, C_usize(bx.cx, size), align, volatile); } pub fn call_memset<'a, 'tcx>(bx: &Builder<'a, 'tcx>, diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index db803ca8209..49bcf9b88a0 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -590,13 +590,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - pub fn volatile_store(&self, val: ValueRef, ptr: ValueRef) -> ValueRef { + pub fn volatile_store(&self, val: ValueRef, ptr: ValueRef, align: Align) -> ValueRef { debug!("Store {:?} -> {:?}", Value(val), Value(ptr)); assert!(!self.llbuilder.is_null()); self.count_insn("store.volatile"); let ptr = self.check_store(val, ptr); unsafe { let insn = llvm::LLVMBuildStore(self.llbuilder, val, ptr); + llvm::LLVMSetAlignment(insn, align.abi() as c_uint); llvm::LLVMSetVolatile(insn, llvm::True); insn } diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 49a207a2d8a..65e211ae740 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -247,26 +247,11 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, to_immediate(bx, load, cx.layout_of(tp_ty)) }, "volatile_store" => { - let tp_ty = substs.type_at(0); let dst = args[0].deref(bx.cx); - if let OperandValue::Pair(a, b) = args[1].val { - bx.volatile_store(a, dst.project_field(bx, 0).llval); - bx.volatile_store(b, dst.project_field(bx, 1).llval); - } else { - let val = if let OperandValue::Ref(ptr, align) = args[1].val { - bx.load(ptr, align) - } else { - if dst.layout.is_zst() { - return; - } - from_immediate(bx, args[1].immediate()) - }; - let ptr = bx.pointercast(dst.llval, val_ty(val).ptr_to()); - let store = bx.volatile_store(val, ptr); - unsafe { - llvm::LLVMSetAlignment(store, cx.align_of(tp_ty).abi() as u32); - } + if dst.layout.is_zst() { + return; } + args[1].val.volatile_store(bx, dst); return; }, "prefetch_read_data" | "prefetch_write_data" | diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index b666c2b2115..df8807c318b 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -626,7 +626,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { // have scary latent bugs around. let scratch = PlaceRef::alloca(bx, arg.layout, "arg"); - base::memcpy_ty(bx, scratch.llval, llval, op.layout, align); + base::memcpy_ty(bx, scratch.llval, llval, op.layout, align, false); (scratch.llval, scratch.align, true) } else { (llval, align, true) diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs index 432ac44e0a5..f6966178291 100644 --- a/src/librustc_trans/mir/operand.rs +++ b/src/librustc_trans/mir/operand.rs @@ -275,6 +275,14 @@ impl<'a, 'tcx> OperandRef<'tcx> { impl<'a, 'tcx> OperandValue { pub fn store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { + self.store_maybe_volatile(bx, dest, false); + } + + pub fn volatile_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { + self.store_maybe_volatile(bx, dest, true); + } + + fn store_maybe_volatile(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>, volatile: bool) { debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest); // Avoid generating stores of zero-sized values, because the only way to have a zero-sized // value is through `undef`, and store itself is useless. @@ -284,9 +292,14 @@ impl<'a, 'tcx> OperandValue { match self { OperandValue::Ref(r, source_align) => base::memcpy_ty(bx, dest.llval, r, dest.layout, - source_align.min(dest.align)), + source_align.min(dest.align), volatile), OperandValue::Immediate(s) => { - bx.store(base::from_immediate(bx, s), dest.llval, dest.align); + let val = base::from_immediate(bx, s); + if !volatile { + bx.store(val, dest.llval, dest.align); + } else { + bx.volatile_store(val, dest.llval, dest.align); + } } OperandValue::Pair(a, b) => { for (i, &x) in [a, b].iter().enumerate() { @@ -295,7 +308,12 @@ impl<'a, 'tcx> OperandValue { if common::val_ty(x) == Type::i1(bx.cx) { llptr = bx.pointercast(llptr, Type::i8p(bx.cx)); } - bx.store(base::from_immediate(bx, x), llptr, dest.align); + let val = base::from_immediate(bx, x); + if !volatile { + bx.store(val, llptr, dest.align); + } else { + bx.volatile_store(val, llptr, dest.align); + } } } } -- cgit 1.4.1-3-g733a5 From 3ebe8679d2eed3caf30d8c6164405916de38ef94 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Fri, 11 May 2018 12:26:32 +0200 Subject: Introduce OperandValue::nontemporal_store and use it in the intrinsics We use a new MemFlags bitflags type to merge some store code paths. --- src/Cargo.lock | 1 + src/librustc_trans/Cargo.toml | 1 + src/librustc_trans/abi.rs | 4 +-- src/librustc_trans/base.rs | 19 +++++++---- src/librustc_trans/builder.rs | 67 ++++++++++++++++++--------------------- src/librustc_trans/intrinsic.rs | 17 ++-------- src/librustc_trans/lib.rs | 1 + src/librustc_trans/mir/block.rs | 4 +-- src/librustc_trans/mir/operand.rs | 29 ++++++++--------- 9 files changed, 65 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/Cargo.lock b/src/Cargo.lock index 4cb82f94251..70a230cb7f7 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -2178,6 +2178,7 @@ dependencies = [ name = "rustc_trans" version = "0.0.0" dependencies = [ + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml index a4dd02e97b2..64d3a4f4d53 100644 --- a/src/librustc_trans/Cargo.toml +++ b/src/librustc_trans/Cargo.toml @@ -10,6 +10,7 @@ crate-type = ["dylib"] test = false [dependencies] +bitflags = "1.0.1" cc = "1.0.1" flate2 = "1.0" jobserver = "0.1.5" diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index c80d989e3cb..25c598c532c 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -10,7 +10,7 @@ use llvm::{self, ValueRef, AttributePlace}; use base; -use builder::Builder; +use builder::{Builder, MemFlags}; use common::{ty_fn_sig, C_usize}; use context::CodegenCx; use mir::place::PlaceRef; @@ -221,7 +221,7 @@ impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> { bx.pointercast(llscratch, Type::i8p(cx)), C_usize(cx, self.layout.size.bytes()), self.layout.align.min(scratch_align), - false); + MemFlags::empty()); bx.lifetime_end(llscratch, scratch_size); } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 65dce5f3ffb..feca36fa6c2 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -53,7 +53,7 @@ use rustc_incremental; use allocator; use mir::place::PlaceRef; use attributes; -use builder::Builder; +use builder::{Builder, MemFlags}; use callee; use common::{C_bool, C_bytes_in_context, C_i32, C_usize}; use rustc_mir::monomorphize::collector::{self, MonoItemCollectionMode}; @@ -320,7 +320,7 @@ pub fn coerce_unsized_into<'a, 'tcx>(bx: &Builder<'a, 'tcx>, if src_f.layout.ty == dst_f.layout.ty { memcpy_ty(bx, dst_f.llval, src_f.llval, src_f.layout, - src_f.align.min(dst_f.align), false); + src_f.align.min(dst_f.align), MemFlags::empty()); } else { coerce_unsized_into(bx, src_f, dst_f); } @@ -409,7 +409,14 @@ pub fn call_memcpy(bx: &Builder, src: ValueRef, n_bytes: ValueRef, align: Align, - volatile: bool) { + flags: MemFlags) { + if flags.contains(MemFlags::NONTEMPORAL) { + // HACK(nox): This is inefficient but there is no nontemporal memcpy. + let val = bx.load(src, align); + let ptr = bx.pointercast(dst, val_ty(val).ptr_to()); + bx.store_with_flags(val, ptr, align, flags); + return; + } let cx = bx.cx; let ptr_width = &cx.sess().target.target.target_pointer_width; let key = format!("llvm.memcpy.p0i8.p0i8.i{}", ptr_width); @@ -418,7 +425,7 @@ pub fn call_memcpy(bx: &Builder, let dst_ptr = bx.pointercast(dst, Type::i8p(cx)); let size = bx.intcast(n_bytes, cx.isize_ty, false); let align = C_i32(cx, align.abi() as i32); - let volatile = C_bool(cx, volatile); + let volatile = C_bool(cx, flags.contains(MemFlags::VOLATILE)); bx.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None); } @@ -428,14 +435,14 @@ pub fn memcpy_ty<'a, 'tcx>( src: ValueRef, layout: TyLayout<'tcx>, align: Align, - volatile: bool, + flags: MemFlags, ) { let size = layout.size.bytes(); if size == 0 { return; } - call_memcpy(bx, dst, src, C_usize(bx.cx, size), align, volatile); + call_memcpy(bx, dst, src, C_usize(bx.cx, size), align, flags); } pub fn call_memset<'a, 'tcx>(bx: &Builder<'a, 'tcx>, diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 49bcf9b88a0..4153c61e526 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -50,6 +50,13 @@ fn noname() -> *const c_char { &CNULL } +bitflags! { + pub struct MemFlags: u8 { + const VOLATILE = 1 << 0; + const NONTEMPORAL = 1 << 1; + } +} + impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn new_block<'b>(cx: &'a CodegenCx<'a, 'tcx>, llfn: ValueRef, name: &'b str) -> Self { let bx = Builder::with_cx(cx); @@ -579,30 +586,39 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } pub fn store(&self, val: ValueRef, ptr: ValueRef, align: Align) -> ValueRef { - debug!("Store {:?} -> {:?}", Value(val), Value(ptr)); + self.store_with_flags(val, ptr, align, MemFlags::empty()) + } + + pub fn store_with_flags( + &self, + val: ValueRef, + ptr: ValueRef, + align: Align, + flags: MemFlags, + ) -> ValueRef { + debug!("Store {:?} -> {:?} ({:?})", Value(val), Value(ptr), flags); assert!(!self.llbuilder.is_null()); self.count_insn("store"); let ptr = self.check_store(val, ptr); unsafe { let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr); llvm::LLVMSetAlignment(store, align.abi() as c_uint); + if flags.contains(MemFlags::VOLATILE) { + llvm::LLVMSetVolatile(store, llvm::True); + } + if flags.contains(MemFlags::NONTEMPORAL) { + // According to LLVM [1] building a nontemporal store must + // *always* point to a metadata value of the integer 1. + // + // [1]: http://llvm.org/docs/LangRef.html#store-instruction + let one = C_i32(self.cx, 1); + let node = llvm::LLVMMDNodeInContext(self.cx.llcx, &one, 1); + llvm::LLVMSetMetadata(store, llvm::MD_nontemporal as c_uint, node); + } store } } - pub fn volatile_store(&self, val: ValueRef, ptr: ValueRef, align: Align) -> ValueRef { - debug!("Store {:?} -> {:?}", Value(val), Value(ptr)); - assert!(!self.llbuilder.is_null()); - self.count_insn("store.volatile"); - let ptr = self.check_store(val, ptr); - unsafe { - let insn = llvm::LLVMBuildStore(self.llbuilder, val, ptr); - llvm::LLVMSetAlignment(insn, align.abi() as c_uint); - llvm::LLVMSetVolatile(insn, llvm::True); - insn - } - } - pub fn atomic_store(&self, val: ValueRef, ptr: ValueRef, order: AtomicOrdering, align: Align) { debug!("Store {:?} -> {:?}", Value(val), Value(ptr)); @@ -616,29 +632,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - pub fn nontemporal_store(&self, val: ValueRef, ptr: ValueRef) -> ValueRef { - debug!("Store {:?} -> {:?}", Value(val), Value(ptr)); - assert!(!self.llbuilder.is_null()); - self.count_insn("store.nontemporal"); - let ptr = self.check_store(val, ptr); - unsafe { - let insn = llvm::LLVMBuildStore(self.llbuilder, val, ptr); - - // According to LLVM [1] building a nontemporal store must *always* - // point to a metadata value of the integer 1. Who knew? - // - // [1]: http://llvm.org/docs/LangRef.html#store-instruction - let one = C_i32(self.cx, 1); - let node = llvm::LLVMMDNodeInContext(self.cx.llcx, - &one, - 1); - llvm::LLVMSetMetadata(insn, - llvm::MD_nontemporal as c_uint, - node); - insn - } - } - pub fn gep(&self, ptr: ValueRef, indices: &[ValueRef]) -> ValueRef { self.count_insn("gep"); unsafe { diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 65e211ae740..86aa48b6a9e 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -248,9 +248,6 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, }, "volatile_store" => { let dst = args[0].deref(bx.cx); - if dst.layout.is_zst() { - return; - } args[1].val.volatile_store(bx, dst); return; }, @@ -536,19 +533,9 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, } "nontemporal_store" => { - let tp_ty = substs.type_at(0); let dst = args[0].deref(bx.cx); - let val = if let OperandValue::Ref(ptr, align) = args[1].val { - bx.load(ptr, align) - } else { - from_immediate(bx, args[1].immediate()) - }; - let ptr = bx.pointercast(dst.llval, val_ty(val).ptr_to()); - let store = bx.nontemporal_store(val, ptr); - unsafe { - llvm::LLVMSetAlignment(store, cx.align_of(tp_ty).abi() as u32); - } - return + args[1].val.nontemporal_store(bx, dst); + return; } _ => { diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 30780b8c965..6db95657ce0 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -34,6 +34,7 @@ use rustc::dep_graph::WorkProduct; use syntax_pos::symbol::Symbol; +#[macro_use] extern crate bitflags; extern crate flate2; extern crate libc; #[macro_use] extern crate rustc; diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index df8807c318b..e4989da36c0 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -17,7 +17,7 @@ use rustc::mir::interpret::EvalErrorKind; use abi::{Abi, ArgType, ArgTypeExt, FnType, FnTypeExt, LlvmType, PassMode}; use base; use callee; -use builder::Builder; +use builder::{Builder, MemFlags}; use common::{self, C_bool, C_str_slice, C_struct, C_u32, C_uint_big, C_undef}; use consts; use meth; @@ -626,7 +626,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { // have scary latent bugs around. let scratch = PlaceRef::alloca(bx, arg.layout, "arg"); - base::memcpy_ty(bx, scratch.llval, llval, op.layout, align, false); + base::memcpy_ty(bx, scratch.llval, llval, op.layout, align, MemFlags::empty()); (scratch.llval, scratch.align, true) } else { (llval, align, true) diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs index f6966178291..3e4a73c2e90 100644 --- a/src/librustc_trans/mir/operand.rs +++ b/src/librustc_trans/mir/operand.rs @@ -18,7 +18,7 @@ use rustc_data_structures::indexed_vec::Idx; use base; use common::{self, CodegenCx, C_null, C_undef, C_usize}; -use builder::Builder; +use builder::{Builder, MemFlags}; use value::Value; use type_of::LayoutLlvmExt; use type_::Type; @@ -275,14 +275,18 @@ impl<'a, 'tcx> OperandRef<'tcx> { impl<'a, 'tcx> OperandValue { pub fn store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { - self.store_maybe_volatile(bx, dest, false); + self.store_with_flags(bx, dest, MemFlags::empty()); } pub fn volatile_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { - self.store_maybe_volatile(bx, dest, true); + self.store_with_flags(bx, dest, MemFlags::VOLATILE); } - fn store_maybe_volatile(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>, volatile: bool) { + pub fn nontemporal_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { + self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL); + } + + fn store_with_flags(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>, flags: MemFlags) { debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest); // Avoid generating stores of zero-sized values, because the only way to have a zero-sized // value is through `undef`, and store itself is useless. @@ -290,16 +294,13 @@ impl<'a, 'tcx> OperandValue { return; } match self { - OperandValue::Ref(r, source_align) => + OperandValue::Ref(r, source_align) => { base::memcpy_ty(bx, dest.llval, r, dest.layout, - source_align.min(dest.align), volatile), + source_align.min(dest.align), flags) + } OperandValue::Immediate(s) => { let val = base::from_immediate(bx, s); - if !volatile { - bx.store(val, dest.llval, dest.align); - } else { - bx.volatile_store(val, dest.llval, dest.align); - } + bx.store_with_flags(val, dest.llval, dest.align, flags); } OperandValue::Pair(a, b) => { for (i, &x) in [a, b].iter().enumerate() { @@ -309,11 +310,7 @@ impl<'a, 'tcx> OperandValue { llptr = bx.pointercast(llptr, Type::i8p(bx.cx)); } let val = base::from_immediate(bx, x); - if !volatile { - bx.store(val, llptr, dest.align); - } else { - bx.volatile_store(val, llptr, dest.align); - } + bx.store_with_flags(val, llptr, dest.align, flags); } } } -- cgit 1.4.1-3-g733a5 From 394945ee36301f0e2be2aa711d9fe6c063960083 Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Wed, 2 May 2018 03:02:05 +0000 Subject: stabilize :lifetime --- .../src/language-features/macro-lifetime-matcher.md | 14 -------------- src/librustc/lib.rs | 1 - src/librustc_metadata/lib.rs | 2 -- src/librustc_save_analysis/lib.rs | 1 - src/libsyntax/ext/tt/macro_rules.rs | 14 +------------- src/libsyntax/feature_gate.rs | 8 ++------ src/test/run-pass/macro-lifetime-used-with-bound.rs | 2 -- src/test/run-pass/macro-lifetime-used-with-labels.rs | 1 - src/test/run-pass/macro-lifetime-used-with-static.rs | 2 -- src/test/run-pass/macro-lifetime.rs | 2 -- src/test/ui/feature-gate-macro-lifetime-matcher.rs | 19 ------------------- src/test/ui/macros/nonterminal-matching.rs | 2 +- 12 files changed, 4 insertions(+), 64 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/macro-lifetime-matcher.md delete mode 100644 src/test/ui/feature-gate-macro-lifetime-matcher.rs (limited to 'src') diff --git a/src/doc/unstable-book/src/language-features/macro-lifetime-matcher.md b/src/doc/unstable-book/src/language-features/macro-lifetime-matcher.md deleted file mode 100644 index 5b585d7f041..00000000000 --- a/src/doc/unstable-book/src/language-features/macro-lifetime-matcher.md +++ /dev/null @@ -1,14 +0,0 @@ -# `macro_lifetime_matcher` - -The tracking issue for this feature is: [#46895] - -With this feature gate enabled, the [list of fragment specifiers][frags] gains one more entry: - -* `lifetime`: a lifetime. Examples: 'static, 'a. - -A `lifetime` variable may be followed by anything. - -[#46895]: https://github.com/rust-lang/rust/issues/46895 -[frags]: ../book/first-edition/macros.html#syntactic-requirements - ------------------------- diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 879d38c4894..b9928a08131 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -50,7 +50,6 @@ #![feature(from_ref)] #![feature(fs_read_write)] #![cfg_attr(windows, feature(libc))] -#![feature(macro_lifetime_matcher)] #![feature(macro_vis_matcher)] #![feature(never_type)] #![feature(exhaustive_patterns)] diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index a99e0a32e66..60016a0d864 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -15,9 +15,7 @@ #![feature(box_patterns)] #![feature(fs_read_write)] #![feature(libc)] -#![feature(macro_lifetime_matcher)] #![feature(proc_macro_internals)] -#![feature(macro_lifetime_matcher)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(slice_sort_by_cached_key)] diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index cf12302d989..bfcb23c1fb8 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -12,7 +12,6 @@ html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(custom_attribute)] -#![feature(macro_lifetime_matcher)] #![allow(unused_attributes)] #[macro_use] diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 1fc5aed7e7a..e96a0e838cf 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -904,20 +904,8 @@ fn is_legal_fragment_specifier(sess: &ParseSess, frag_name: &str, frag_span: Span) -> bool { match frag_name { - "item" | "block" | "stmt" | "expr" | "pat" | + "item" | "block" | "stmt" | "expr" | "pat" | "lifetime" | "path" | "ty" | "ident" | "meta" | "tt" | "" => true, - "lifetime" => { - if !features.macro_lifetime_matcher && - !attr::contains_name(attrs, "allow_internal_unstable") { - let explain = feature_gate::EXPLAIN_LIFETIME_MATCHER; - emit_feature_err(sess, - "macro_lifetime_matcher", - frag_span, - GateIssue::Language, - explain); - } - true - }, "literal" => { if !features.macro_literal_matcher && !attr::contains_name(attrs, "allow_internal_unstable") { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 562705462e2..cb5125fe9ef 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -396,9 +396,6 @@ declare_features! ( // Termination trait in tests (RFC 1937) (active, termination_trait_test, "1.24.0", Some(48854), Some(Edition::Edition2018)), - // Allows use of the :lifetime macro fragment specifier - (active, macro_lifetime_matcher, "1.24.0", Some(46895), None), - // `extern` in paths (active, extern_in_paths, "1.23.0", Some(44660), None), @@ -598,6 +595,8 @@ declare_features! ( (accepted, dyn_trait, "1.27.0", Some(44662), None), // allow `#[must_use]` on functions; and, must-use operators (RFC 1940) (accepted, fn_must_use, "1.27.0", Some(43302), None), + // Allows use of the :lifetime macro fragment specifier + (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None), ); // If you change this, please modify src/doc/unstable-book as well. You must @@ -1331,9 +1330,6 @@ pub const EXPLAIN_DERIVE_UNDERSCORE: &'static str = pub const EXPLAIN_VIS_MATCHER: &'static str = ":vis fragment specifier is experimental and subject to change"; -pub const EXPLAIN_LIFETIME_MATCHER: &'static str = - ":lifetime fragment specifier is experimental and subject to change"; - pub const EXPLAIN_LITERAL_MATCHER: &'static str = ":literal fragment specifier is experimental and subject to change"; diff --git a/src/test/run-pass/macro-lifetime-used-with-bound.rs b/src/test/run-pass/macro-lifetime-used-with-bound.rs index b0c9280b6ce..b9e1fde6b1f 100644 --- a/src/test/run-pass/macro-lifetime-used-with-bound.rs +++ b/src/test/run-pass/macro-lifetime-used-with-bound.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(macro_lifetime_matcher)] - macro_rules! foo { ($l:lifetime, $l2:lifetime) => { fn f<$l: $l2, $l2>(arg: &$l str, arg2: &$l2 str) -> &$l str { diff --git a/src/test/run-pass/macro-lifetime-used-with-labels.rs b/src/test/run-pass/macro-lifetime-used-with-labels.rs index 8a2d76e17df..d003d7dcfb6 100644 --- a/src/test/run-pass/macro-lifetime-used-with-labels.rs +++ b/src/test/run-pass/macro-lifetime-used-with-labels.rs @@ -9,7 +9,6 @@ // except according to those terms. #![allow(unreachable_code)] -#![feature(macro_lifetime_matcher)] macro_rules! x { ($a:lifetime) => { diff --git a/src/test/run-pass/macro-lifetime-used-with-static.rs b/src/test/run-pass/macro-lifetime-used-with-static.rs index 468ee2e9436..5c1f8683e00 100644 --- a/src/test/run-pass/macro-lifetime-used-with-static.rs +++ b/src/test/run-pass/macro-lifetime-used-with-static.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(macro_lifetime_matcher)] - macro_rules! foo { ($l:lifetime) => { fn f(arg: &$l str) -> &$l str { diff --git a/src/test/run-pass/macro-lifetime.rs b/src/test/run-pass/macro-lifetime.rs index db521ca7f10..ff5798ff78d 100644 --- a/src/test/run-pass/macro-lifetime.rs +++ b/src/test/run-pass/macro-lifetime.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(macro_lifetime_matcher)] - macro_rules! foo { ($l:lifetime) => { fn f<$l>(arg: &$l str) -> &$l str { diff --git a/src/test/ui/feature-gate-macro-lifetime-matcher.rs b/src/test/ui/feature-gate-macro-lifetime-matcher.rs deleted file mode 100644 index 0d107d283cd..00000000000 --- a/src/test/ui/feature-gate-macro-lifetime-matcher.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2017 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. - -// Test that the :lifetime macro fragment cannot be used when macro_lifetime_matcher -// feature gate is not used. - -macro_rules! m { ($lt:lifetime) => {} } -//~^ ERROR :lifetime fragment specifier is experimental and subject to change - -fn main() { - m!('a); -} diff --git a/src/test/ui/macros/nonterminal-matching.rs b/src/test/ui/macros/nonterminal-matching.rs index 4dcb8afa94e..54d280a63e7 100644 --- a/src/test/ui/macros/nonterminal-matching.rs +++ b/src/test/ui/macros/nonterminal-matching.rs @@ -11,7 +11,7 @@ // Check that we are refusing to match on complex nonterminals for which tokens are // unavailable and we'd have to go through AST comparisons. -#![feature(decl_macro, macro_lifetime_matcher)] +#![feature(decl_macro)] macro simple_nonterminal($nt_ident: ident, $nt_lifetime: lifetime, $nt_tt: tt) { macro n(a $nt_ident b $nt_lifetime c $nt_tt d) { -- cgit 1.4.1-3-g733a5 From e6f7cf7e75286ca0e298bcdce7d831e5ebd451df Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Wed, 2 May 2018 04:38:08 +0000 Subject: remove stray ui stderr --- src/test/ui/feature-gate-macro-lifetime-matcher.stderr | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 src/test/ui/feature-gate-macro-lifetime-matcher.stderr (limited to 'src') diff --git a/src/test/ui/feature-gate-macro-lifetime-matcher.stderr b/src/test/ui/feature-gate-macro-lifetime-matcher.stderr deleted file mode 100644 index b7805f6f5fb..00000000000 --- a/src/test/ui/feature-gate-macro-lifetime-matcher.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: :lifetime fragment specifier is experimental and subject to change (see issue #46895) - --> $DIR/feature-gate-macro-lifetime-matcher.rs:14:19 - | -LL | macro_rules! m { ($lt:lifetime) => {} } - | ^^^^^^^^^^^^ - | - = help: add #![feature(macro_lifetime_matcher)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. -- cgit 1.4.1-3-g733a5 From e857c1b79028765c62e7f29584c7ce75bfb739b9 Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Thu, 10 May 2018 02:01:03 +0000 Subject: restore feature for stage0 --- src/librustc/lib.rs | 1 + src/librustc_metadata/lib.rs | 1 + src/librustc_save_analysis/lib.rs | 1 + 3 files changed, 3 insertions(+) (limited to 'src') diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index b9928a08131..2a288ae522a 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -50,6 +50,7 @@ #![feature(from_ref)] #![feature(fs_read_write)] #![cfg_attr(windows, feature(libc))] +#![cfg_attr(stage0, feature(macro_lifetime_matcher))] #![feature(macro_vis_matcher)] #![feature(never_type)] #![feature(exhaustive_patterns)] diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 60016a0d864..7ecf2eba43d 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -15,6 +15,7 @@ #![feature(box_patterns)] #![feature(fs_read_write)] #![feature(libc)] +#![cfg_attr(stage0, feature(macro_lifetime_matcher))] #![feature(proc_macro_internals)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index bfcb23c1fb8..e57a793ff42 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -12,6 +12,7 @@ html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(custom_attribute)] +#![cfg_attr(stage0, feature(macro_lifetime_matcher))] #![allow(unused_attributes)] #[macro_use] -- cgit 1.4.1-3-g733a5 From cdd61396c93f34915d145f0ab5b388138b479a3c Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Sat, 12 May 2018 19:04:44 +0000 Subject: typeck: Save the index of private fields Save the index of all fields regardless of their visibility. Problems could occur later when attempting to index fields in error recovery if they are not inserted. --- src/librustc_typeck/check/mod.rs | 4 ++- .../proc-macro/auxiliary/issue_50493.rs | 32 ++++++++++++++++++++++ .../proc-macro/issue-50493.rs | 27 ++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue_50493.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/issue-50493.rs (limited to 'src') diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 7b859635f60..e38a00bba16 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3081,12 +3081,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(index) = fields.iter().position(|f| f.name.to_ident() == ident) { let field = &fields[index]; let field_ty = self.field_ty(expr.span, field, substs); + // Save the index of all fields regardless of their visibility in case + // of error recovery. + self.write_field_index(expr.id, index); if field.vis.is_accessible_from(def_scope, self.tcx) { let adjustments = autoderef.adjust_steps(needs); self.apply_adjustments(base, adjustments); autoderef.finalize(); - self.write_field_index(expr.id, index); self.tcx.check_stability(field.did, Some(expr.id), expr.span); return field_ty; } diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue_50493.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue_50493.rs new file mode 100644 index 00000000000..7d36517d970 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue_50493.rs @@ -0,0 +1,32 @@ +// Copyright 2016 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. + +// force-host +// no-prefer-dynamic + +#![feature(proc_macro, proc_macro_lib)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_derive(Derive)] +pub fn derive(_: TokenStream) -> TokenStream { + let code = " + fn one(r: Restricted) { + r.field; + } + fn two(r: Restricted) { + r.field; + } + "; + + code.parse().unwrap() +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-50493.rs b/src/test/compile-fail-fulldeps/proc-macro/issue-50493.rs new file mode 100644 index 00000000000..51112f202c8 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/issue-50493.rs @@ -0,0 +1,27 @@ +// Copyright 2016 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. + +// aux-build:issue_50493.rs +// ignore-stage1 + +#![feature(proc_macro)] + +#[macro_use] +extern crate issue_50493; + +#[derive(Derive)] //~ ERROR field `field` of struct `Restricted` is private +struct Restricted { + pub(in restricted) field: usize, //~ visibilities can only be restricted to ancestor modules +} + +mod restricted {} + +fn main() {} + -- cgit 1.4.1-3-g733a5 From 29b4c7b9e0a5e32127c42f5aab9baefadc38033c Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 14 May 2018 12:23:12 +0300 Subject: rustc: don't trip an assertion for enums with present but uninhabited variants. --- src/librustc/ty/layout.rs | 5 +++++ src/test/run-pass/issue-50731.rs | 15 +++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 src/test/run-pass/issue-50731.rs (limited to 'src') diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index b22c025e86c..bbfc6d883e9 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -888,6 +888,11 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { if x < min { min = x; } if x > max { max = x; } } + // We might have no inhabited variants, so pretend there's at least one. + if (min, max) == (i128::max_value(), i128::min_value()) { + min = 0; + max = 0; + } assert!(min <= max, "discriminant range is {}...{}", min, max); let (min_ity, signed) = Integer::repr_discr(tcx, ty, &def.repr, min, max); diff --git a/src/test/run-pass/issue-50731.rs b/src/test/run-pass/issue-50731.rs new file mode 100644 index 00000000000..06df2b989af --- /dev/null +++ b/src/test/run-pass/issue-50731.rs @@ -0,0 +1,15 @@ +// Copyright 2018 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. + +enum Void {} +fn foo(_: Result<(Void, u32), (Void, String)>) {} +fn main() { + let _: fn(_) = foo; +} -- cgit 1.4.1-3-g733a5 From 3a5b13ad36d5cb4081c727c78e7d6fd6711108b9 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 14 May 2018 16:11:24 +0200 Subject: Bump clippy --- src/Cargo.lock | 6 +++--- src/tools/clippy | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Cargo.lock b/src/Cargo.lock index 70a230cb7f7..2f52c889558 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -288,12 +288,12 @@ dependencies = [ [[package]] name = "clippy" -version = "0.0.198" +version = "0.0.200" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "clippy-mini-macro-test 0.2.0", - "clippy_lints 0.0.198", + "clippy_lints 0.0.200", "compiletest_rs 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -331,7 +331,7 @@ dependencies = [ [[package]] name = "clippy_lints" -version = "0.0.198" +version = "0.0.200" dependencies = [ "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/tools/clippy b/src/tools/clippy index 7a4c00c669b..c658fc8cbcd 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 7a4c00c669b3bf0ffb24c7aa89a776cd48f1e2d0 +Subproject commit c658fc8cbcd1f199edd445a49cb43139ebdc5f02 -- cgit 1.4.1-3-g733a5 From 647b1add7fc1cb3204131f82cbbe67eb9b4a27b3 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Mon, 14 May 2018 12:32:04 -0400 Subject: Update stdsimd module to include https://github.com/rust-lang-nursery/stdsimd/commit/a19ca1cd91cf97777af8268a6136bd2e4648e189 --- src/stdsimd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/stdsimd b/src/stdsimd index 2f86c75a247..a19ca1cd91c 160000 --- a/src/stdsimd +++ b/src/stdsimd @@ -1 +1 @@ -Subproject commit 2f86c75a2479cf051b92fc98273daaf7f151e7a1 +Subproject commit a19ca1cd91cf97777af8268a6136bd2e4648e189 -- cgit 1.4.1-3-g733a5