From c04d86deeb6d23d8ee4b31abda92bb84c1d17897 Mon Sep 17 00:00:00 2001 From: roblabla Date: Mon, 29 Jan 2018 11:07:11 +0100 Subject: [PATCH 01/18] Work around LLVM OCAML binding installation failure --- src/bootstrap/native.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 3f30756a568ce..bb482813a23fe 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -155,6 +155,7 @@ impl Step for Llvm { .define("WITH_POLLY", "OFF") .define("LLVM_ENABLE_TERMINFO", "OFF") .define("LLVM_ENABLE_LIBEDIT", "OFF") + .define("LLVM_OCAML_INSTALL_PATH", "usr/lib/ocaml") .define("LLVM_PARALLEL_COMPILE_JOBS", build.jobs().to_string()) .define("LLVM_TARGET_ARCH", target.split('-').next().unwrap()) .define("LLVM_DEFAULT_TARGET_TRIPLE", target); From 4f8049a2b00c46cb1ac77cabaaf716895f185afe Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 9 Feb 2018 01:47:18 -0800 Subject: [PATCH 02/18] Add Range[Inclusive]::is_empty During the RFC, it was discussed that figuring out whether a range is empty was subtle, and thus there should be a clear and obvious way to do it. It can't just be ExactSizeIterator::is_empty (also unstable) because not all ranges are ExactSize -- not even Range or RangeInclusive. --- src/libcore/iter/traits.rs | 2 +- src/libcore/ops/range.rs | 36 ++++++++++++++++++++++++++++++++++-- src/libcore/tests/iter.rs | 4 ++-- src/libcore/tests/lib.rs | 1 + src/libcore/tests/ops.rs | 24 ++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs index be4889f24877c..860742d9eab60 100644 --- a/src/libcore/iter/traits.rs +++ b/src/libcore/iter/traits.rs @@ -706,7 +706,7 @@ pub trait ExactSizeIterator: Iterator { /// ``` /// #![feature(exact_size_is_empty)] /// - /// let mut one_element = 0..1; + /// let mut one_element = std::iter::once(0); /// assert!(!one_element.is_empty()); /// /// assert_eq!(one_element.next(), Some(0)); diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 3f573f7c7eb69..102e08362cb4c 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -92,7 +92,6 @@ impl fmt::Debug for Range { } } -#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] impl> Range { /// Returns `true` if `item` is contained in the range. /// @@ -109,9 +108,26 @@ impl> Range { /// assert!(!(3..3).contains(3)); /// assert!(!(3..2).contains(3)); /// ``` + #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] pub fn contains(&self, item: Idx) -> bool { (self.start <= item) && (item < self.end) } + + /// Returns `true` if the range contains no items. + /// + /// # Examples + /// + /// ``` + /// #![feature(range_is_empty)] + /// + /// assert!(!(3..5).is_empty()); + /// assert!( (3..3).is_empty()); + /// assert!( (3..2).is_empty()); + /// ``` + #[unstable(feature = "range_is_empty", reason = "recently added", issue = "123456789")] + pub fn is_empty(&self) -> bool { + !(self.start < self.end) + } } /// A range only bounded inclusively below (`start..`). @@ -280,7 +296,6 @@ impl fmt::Debug for RangeInclusive { } } -#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] impl> RangeInclusive { /// Returns `true` if `item` is contained in the range. /// @@ -298,9 +313,26 @@ impl> RangeInclusive { /// assert!( (3..=3).contains(3)); /// assert!(!(3..=2).contains(3)); /// ``` + #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] pub fn contains(&self, item: Idx) -> bool { self.start <= item && item <= self.end } + + /// Returns `true` if the range contains no items. + /// + /// # Examples + /// + /// ``` + /// #![feature(range_is_empty,inclusive_range_syntax)] + /// + /// assert!(!(3..=5).is_empty()); + /// assert!(!(3..=3).is_empty()); + /// assert!( (3..=2).is_empty()); + /// ``` + #[unstable(feature = "range_is_empty", reason = "recently added", issue = "123456789")] + pub fn is_empty(&self) -> bool { + !(self.start <= self.end) + } } /// A range only bounded inclusively above (`..=end`). diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index b2a5243d5e67b..062b6d4126e2c 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1427,9 +1427,9 @@ fn test_range_inclusive_nth() { assert_eq!(r, 13..=20); assert_eq!(r.nth(2), Some(15)); assert_eq!(r, 16..=20); - assert_eq!(r.is_empty(), false); + assert_eq!(ExactSizeIterator::is_empty(&r), false); assert_eq!(r.nth(10), None); - assert_eq!(r.is_empty(), true); + assert_eq!(ExactSizeIterator::is_empty(&r), true); assert_eq!(r, 1..=0); // We may not want to document/promise this detail } diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 1c32452f84635..91b4f02594bc3 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -29,6 +29,7 @@ #![feature(iter_rfold)] #![feature(nonzero)] #![feature(pattern)] +#![feature(range_is_empty)] #![feature(raw)] #![feature(refcell_replace_swap)] #![feature(sip_hash_13)] diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs index 9d2fa1abff658..68a692b24a3fb 100644 --- a/src/libcore/tests/ops.rs +++ b/src/libcore/tests/ops.rs @@ -68,3 +68,27 @@ fn test_range_inclusive() { assert_eq!(r.size_hint(), (0, Some(0))); assert_eq!(r.next(), None); } + + +#[test] +fn test_range_is_empty() { + use core::f32::*; + + assert!(!(0.0 .. 10.0).is_empty()); + assert!( (-0.0 .. 0.0).is_empty()); + assert!( (10.0 .. 0.0).is_empty()); + + assert!(!(NEG_INFINITY .. INFINITY).is_empty()); + assert!( (EPSILON .. NAN).is_empty()); + assert!( (NAN .. EPSILON).is_empty()); + assert!( (NAN .. NAN).is_empty()); + + assert!(!(0.0 ..= 10.0).is_empty()); + assert!(!(-0.0 ..= 0.0).is_empty()); + assert!( (10.0 ..= 0.0).is_empty()); + + assert!(!(NEG_INFINITY ..= INFINITY).is_empty()); + assert!( (EPSILON ..= NAN).is_empty()); + assert!( (NAN ..= EPSILON).is_empty()); + assert!( (NAN ..= NAN).is_empty()); +} \ No newline at end of file From 7fe182fdfe01e01dd899962cc8dbaea63f422c9c Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 9 Feb 2018 02:11:04 -0800 Subject: [PATCH 03/18] Fix tidy --- src/libcore/tests/ops.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs index 68a692b24a3fb..bed08f86d72c1 100644 --- a/src/libcore/tests/ops.rs +++ b/src/libcore/tests/ops.rs @@ -91,4 +91,4 @@ fn test_range_is_empty() { assert!( (EPSILON ..= NAN).is_empty()); assert!( (NAN ..= EPSILON).is_empty()); assert!( (NAN ..= NAN).is_empty()); -} \ No newline at end of file +} From b5cb393cf5b4a65fb99d8b1e43450fb87567788b Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 9 Feb 2018 17:54:27 -0800 Subject: [PATCH 04/18] Use is_empty in range iteration exhaustion tests --- src/libcore/ops/range.rs | 18 ++++++++++++ src/libcore/tests/iter.rs | 61 +++++++++++++++++++++++++++++++++------ 2 files changed, 70 insertions(+), 9 deletions(-) diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 102e08362cb4c..cce593ee208b6 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -262,6 +262,13 @@ impl> RangeTo { /// The `RangeInclusive` `start..=end` contains all values with `x >= start` /// and `x <= end`. /// +/// This iterator is [fused], but the specific values of `start` and `end` after +/// iteration has finished are **unspecified** other than that [`.is_empty()`] +/// will return `true` once no more values will be produced. +/// +/// [fused]: ../iter/trait.FusedIterator.html +/// [`.is_empty()`]: #method.is_empty +/// /// # Examples /// /// ``` @@ -329,6 +336,17 @@ impl> RangeInclusive { /// assert!(!(3..=3).is_empty()); /// assert!( (3..=2).is_empty()); /// ``` + /// + /// This method returns `true` after iteration has finished: + /// + /// ``` + /// #![feature(range_is_empty,inclusive_range_syntax)] + /// + /// let mut r = 3..=5; + /// for _ in r.by_ref() {} + /// // Precise field values are unspecified here + /// assert!(r.is_empty()); + /// ``` #[unstable(feature = "range_is_empty", reason = "recently added", issue = "123456789")] pub fn is_empty(&self) -> bool { !(self.start <= self.end) diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 062b6d4126e2c..d8c9dcd866486 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1322,42 +1322,84 @@ fn test_range() { (isize::MAX as usize + 2, Some(isize::MAX as usize + 2))); } +#[test] +fn test_range_exhaustion() { + let mut r = 10..10; + assert!(r.is_empty()); + assert_eq!(r.next(), None); + assert_eq!(r.next_back(), None); + assert_eq!(r, 10..10); + + let mut r = 10..12; + assert_eq!(r.next(), Some(10)); + assert_eq!(r.next(), Some(11)); + assert!(r.is_empty()); + assert_eq!(r, 12..12); + assert_eq!(r.next(), None); + + let mut r = 10..12; + assert_eq!(r.next_back(), Some(11)); + assert_eq!(r.next_back(), Some(10)); + assert!(r.is_empty()); + assert_eq!(r, 10..10); + assert_eq!(r.next_back(), None); + + let mut r = 100..10; + assert!(r.is_empty()); + assert_eq!(r.next(), None); + assert_eq!(r.next_back(), None); + assert_eq!(r, 100..10); +} + #[test] fn test_range_inclusive_exhaustion() { let mut r = 10..=10; assert_eq!(r.next(), Some(10)); - assert_eq!(r, 1..=0); + assert!(r.is_empty()); + assert_eq!(r.next(), None); + assert_eq!(r.next(), None); let mut r = 10..=10; assert_eq!(r.next_back(), Some(10)); - assert_eq!(r, 1..=0); + assert!(r.is_empty()); + assert_eq!(r.next_back(), None); let mut r = 10..=12; assert_eq!(r.next(), Some(10)); assert_eq!(r.next(), Some(11)); assert_eq!(r.next(), Some(12)); - assert_eq!(r, 1..=0); + assert!(r.is_empty()); + assert_eq!(r.next(), None); let mut r = 10..=12; assert_eq!(r.next_back(), Some(12)); assert_eq!(r.next_back(), Some(11)); assert_eq!(r.next_back(), Some(10)); - assert_eq!(r, 1..=0); + assert!(r.is_empty()); + assert_eq!(r.next_back(), None); let mut r = 10..=12; assert_eq!(r.nth(2), Some(12)); - assert_eq!(r, 1..=0); + assert!(r.is_empty()); + assert_eq!(r.next(), None); let mut r = 10..=12; assert_eq!(r.nth(5), None); - assert_eq!(r, 1..=0); + assert!(r.is_empty()); + assert_eq!(r.next(), None); let mut r = 100..=10; assert_eq!(r.next(), None); + assert!(r.is_empty()); + assert_eq!(r.next(), None); + assert_eq!(r.next(), None); assert_eq!(r, 100..=10); let mut r = 100..=10; assert_eq!(r.next_back(), None); + assert!(r.is_empty()); + assert_eq!(r.next_back(), None); + assert_eq!(r.next_back(), None); assert_eq!(r, 100..=10); } @@ -1427,10 +1469,11 @@ fn test_range_inclusive_nth() { assert_eq!(r, 13..=20); assert_eq!(r.nth(2), Some(15)); assert_eq!(r, 16..=20); + assert_eq!(r.is_empty(), false); assert_eq!(ExactSizeIterator::is_empty(&r), false); assert_eq!(r.nth(10), None); + assert_eq!(r.is_empty(), true); assert_eq!(ExactSizeIterator::is_empty(&r), true); - assert_eq!(r, 1..=0); // We may not want to document/promise this detail } #[test] @@ -1514,11 +1557,11 @@ fn test_range_inclusive_folds() { let mut it = 10..=20; assert_eq!(it.try_fold(0, |a,b| Some(a+b)), Some(165)); - assert_eq!(it, 1..=0); + assert!(it.is_empty()); let mut it = 10..=20; assert_eq!(it.try_rfold(0, |a,b| Some(a+b)), Some(165)); - assert_eq!(it, 1..=0); + assert!(it.is_empty()); } #[test] From 6f70a11a831992fe86a935a0d649d3aa6b16dc50 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 9 Feb 2018 18:01:12 -0800 Subject: [PATCH 05/18] range_is_empty tracking issue is #48111 --- src/libcore/ops/range.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index cce593ee208b6..4e4d334752370 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -124,7 +124,7 @@ impl> Range { /// assert!( (3..3).is_empty()); /// assert!( (3..2).is_empty()); /// ``` - #[unstable(feature = "range_is_empty", reason = "recently added", issue = "123456789")] + #[unstable(feature = "range_is_empty", reason = "recently added", issue = "48111")] pub fn is_empty(&self) -> bool { !(self.start < self.end) } @@ -347,7 +347,7 @@ impl> RangeInclusive { /// // Precise field values are unspecified here /// assert!(r.is_empty()); /// ``` - #[unstable(feature = "range_is_empty", reason = "recently added", issue = "123456789")] + #[unstable(feature = "range_is_empty", reason = "recently added", issue = "48111")] pub fn is_empty(&self) -> bool { !(self.start <= self.end) } From 0cccd9aca51e3fe2952633b34c4c877539d1113d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 6 Feb 2018 14:57:08 +0100 Subject: [PATCH 06/18] Show better warning for trying to cast non-u8 scalar to char --- src/librustc_lint/types.rs | 17 +++++++++++++++++ src/test/ui/cast_char.rs | 20 ++++++++++++++++++++ src/test/ui/cast_char.stderr | 20 ++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 src/test/ui/cast_char.rs create mode 100644 src/test/ui/cast_char.stderr diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index e7e4119b9999b..f734f3182a931 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -11,6 +11,7 @@ #![allow(non_snake_case)] use rustc::hir::def_id::DefId; +use rustc::hir::map as hir_map; use rustc::ty::subst::Substs; use rustc::ty::{self, AdtKind, Ty, TyCtxt}; use rustc::ty::layout::{self, LayoutOf}; @@ -176,6 +177,22 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { _ => bug!(), }; if lit_val < min || lit_val > max { + let parent_id = cx.tcx.hir.get_parent_node(e.id); + if let hir_map::NodeExpr(parent_expr) = cx.tcx.hir.get(parent_id) { + if let hir::ExprCast(..) = parent_expr.node { + if let ty::TyChar = cx.tables.expr_ty(parent_expr).sty { + let mut err = cx.struct_span_lint( + OVERFLOWING_LITERALS, + parent_expr.span, + "only u8 can be casted into char"); + err.span_suggestion(parent_expr.span, + &"use a char literal instead", + format!("'\\u{{{:X}}}'", lit_val)); + err.emit(); + return + } + } + } cx.span_lint(OVERFLOWING_LITERALS, e.span, &format!("literal out of range for {:?}", t)); diff --git a/src/test/ui/cast_char.rs b/src/test/ui/cast_char.rs new file mode 100644 index 0000000000000..cd8ade5e51a1b --- /dev/null +++ b/src/test/ui/cast_char.rs @@ -0,0 +1,20 @@ +// 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. + +#![deny(overflowing_literals)] + +fn main() { + const XYZ: char = 0x1F888 as char; + //~^ ERROR only u8 can be casted into char + const XY: char = 129160 as char; + //~^ ERROR only u8 can be casted into char + const ZYX: char = '\u{01F888}'; + println!("{}", XYZ); +} diff --git a/src/test/ui/cast_char.stderr b/src/test/ui/cast_char.stderr new file mode 100644 index 0000000000000..e42a38dace9d2 --- /dev/null +++ b/src/test/ui/cast_char.stderr @@ -0,0 +1,20 @@ +error: only u8 can be casted into char + --> $DIR/cast_char.rs:14:23 + | +14 | const XYZ: char = 0x1F888 as char; + | ^^^^^^^^^^^^^^^ help: use a char literal instead: `'/u{1F888}'` + | +note: lint level defined here + --> $DIR/cast_char.rs:11:9 + | +11 | #![deny(overflowing_literals)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: only u8 can be casted into char + --> $DIR/cast_char.rs:16:22 + | +16 | const XY: char = 129160 as char; + | ^^^^^^^^^^^^^^ help: use a char literal instead: `'/u{1F888}'` + +error: aborting due to 2 previous errors + From 14f488ee7d05c39b8d6ea2855da274157555df0b Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sat, 10 Feb 2018 19:22:04 +0300 Subject: [PATCH 07/18] Whitelist pclmul x86 feature flag Relevant `stdsimd` [issue](https://github.com/rust-lang-nursery/stdsimd/issues/318). --- src/librustc_trans/llvm_util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 843231d376f6c..f719562b47647 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -88,7 +88,7 @@ const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bm "ssse3\0", "tbm\0", "lzcnt\0", "popcnt\0", "sse4a\0", "rdrnd\0", "rdseed\0", "fma\0", "xsave\0", "xsaveopt\0", "xsavec\0", - "xsaves\0", "aes\0", + "xsaves\0", "aes\0", "pclmul\0" "avx512bw\0", "avx512cd\0", "avx512dq\0", "avx512er\0", "avx512f\0", "avx512ifma\0", From 877272ba066dd81d9d920b851d0300bb3e7ee2b3 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sat, 10 Feb 2018 20:07:37 +0300 Subject: [PATCH 08/18] typo fix --- src/librustc_trans/llvm_util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index f719562b47647..21def37e5e6e5 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -88,7 +88,7 @@ const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bm "ssse3\0", "tbm\0", "lzcnt\0", "popcnt\0", "sse4a\0", "rdrnd\0", "rdseed\0", "fma\0", "xsave\0", "xsaveopt\0", "xsavec\0", - "xsaves\0", "aes\0", "pclmul\0" + "xsaves\0", "aes\0", "pclmul\0", "avx512bw\0", "avx512cd\0", "avx512dq\0", "avx512er\0", "avx512f\0", "avx512ifma\0", From 3c01dea03e1b4ffbcb665a68bcf228c02497ecdc Mon Sep 17 00:00:00 2001 From: roblabla Date: Sat, 10 Feb 2018 21:29:10 +0100 Subject: [PATCH 09/18] Add comment about the problem, and use provided path if available --- src/bootstrap/native.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index bb482813a23fe..108b0159dce74 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -155,11 +155,18 @@ impl Step for Llvm { .define("WITH_POLLY", "OFF") .define("LLVM_ENABLE_TERMINFO", "OFF") .define("LLVM_ENABLE_LIBEDIT", "OFF") - .define("LLVM_OCAML_INSTALL_PATH", "usr/lib/ocaml") .define("LLVM_PARALLEL_COMPILE_JOBS", build.jobs().to_string()) .define("LLVM_TARGET_ARCH", target.split('-').next().unwrap()) .define("LLVM_DEFAULT_TARGET_TRIPLE", target); + // By default, LLVM will automatically find OCaml and, if it finds it, + // install the LLVM bindings in LLVM_OCAML_INSTALL_PATH, which defaults + // to /usr/bin/ocaml. + // This causes problem for non-root builds of Rust. Side-step the issue + // by setting LLVM_OCAML_INSTALL_PATH to a relative path, so it installs + // in the prefix. + cfg.define("LLVM_OCAML_INSTALL_PATH", + env::var_os("LLVM_OCAML_INSTALL_PATH").unwrap_or_else(|| "usr/lib/ocaml".into())); // This setting makes the LLVM tools link to the dynamic LLVM library, // which saves both memory during parallel links and overall disk space From 45d5a420ada9c11f61347fd4c63c7f0234adaea7 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Sat, 10 Feb 2018 21:20:42 +0000 Subject: [PATCH 10/18] Correct a few stability attributes --- src/libcore/num/mod.rs | 6 +++--- src/libcore/ptr.rs | 4 ++-- src/libcore/time.rs | 4 ++-- src/libstd/io/cursor.rs | 2 +- src/libstd/path.rs | 2 +- src/libsyntax/feature_gate.rs | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 1fae88b9c7775..21d4a486b9833 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -2881,7 +2881,7 @@ pub enum FpCategory { issue = "32110")] pub trait Float: Sized { /// Type used by `to_bits` and `from_bits`. - #[stable(feature = "core_float_bits", since = "1.24.0")] + #[stable(feature = "core_float_bits", since = "1.25.0")] type Bits; /// Returns `true` if this value is NaN and false otherwise. @@ -2947,10 +2947,10 @@ pub trait Float: Sized { fn min(self, other: Self) -> Self; /// Raw transmutation to integer. - #[stable(feature = "core_float_bits", since="1.24.0")] + #[stable(feature = "core_float_bits", since="1.25.0")] fn to_bits(self) -> Self::Bits; /// Raw transmutation from integer. - #[stable(feature = "core_float_bits", since="1.24.0")] + #[stable(feature = "core_float_bits", since="1.25.0")] fn from_bits(v: Self::Bits) -> Self; } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 3d84e910fe662..b266771b818e5 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2573,7 +2573,7 @@ impl Clone for NonNull { #[stable(feature = "nonnull", since = "1.25.0")] impl Copy for NonNull { } -#[stable(feature = "nonnull", since = "1.25.0")] +#[unstable(feature = "coerce_unsized", issue = "27732")] impl CoerceUnsized> for NonNull where T: Unsize { } #[stable(feature = "nonnull", since = "1.25.0")] @@ -2621,7 +2621,7 @@ impl hash::Hash for NonNull { } } -#[stable(feature = "nonnull", since = "1.25.0")] +#[unstable(feature = "ptr_internals", issue = "0")] impl From> for NonNull { fn from(unique: Unique) -> Self { NonNull { pointer: unique.pointer } diff --git a/src/libcore/time.rs b/src/libcore/time.rs index 1a0208d2f25b2..b8d0719b9b992 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -7,7 +7,7 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![stable(feature = "duration_core", since = "1.24.0")] +#![stable(feature = "duration_core", since = "1.25.0")] //! Temporal quantification. //! @@ -58,7 +58,7 @@ const MICROS_PER_SEC: u64 = 1_000_000; /// /// let ten_millis = Duration::from_millis(10); /// ``` -#[stable(feature = "duration_core", since = "1.24.0")] +#[stable(feature = "duration", since = "1.3.0")] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)] pub struct Duration { secs: u64, diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index c8447707d5baf..76bcb5fedc94a 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -296,7 +296,7 @@ impl<'a> Write for Cursor<&'a mut [u8]> { fn flush(&mut self) -> io::Result<()> { Ok(()) } } -#[unstable(feature = "cursor_mut_vec", issue = "30132")] +#[stable(feature = "cursor_mut_vec", since = "1.25.0")] impl<'a> Write for Cursor<&'a mut Vec> { fn write(&mut self, buf: &[u8]) -> io::Result { vec_write(&mut self.pos, self.inner, buf) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index ed102c2949ede..e03a182653e5a 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -576,7 +576,7 @@ impl<'a> AsRef for Component<'a> { } } -#[stable(feature = "path_component_asref", since = "1.24.0")] +#[stable(feature = "path_component_asref", since = "1.25.0")] impl<'a> AsRef for Component<'a> { fn as_ref(&self) -> &Path { self.as_os_str().as_ref() diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 9c6520cd874a8..f8dbc4d0f4532 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -538,7 +538,7 @@ declare_features! ( // instead of just the platforms on which it is the C ABI (accepted, abi_sysv64, "1.24.0", Some(36167)), // Allows `repr(align(16))` struct attribute (RFC 1358) - (accepted, repr_align, "1.24.0", Some(33626)), + (accepted, repr_align, "1.25.0", Some(33626)), // allow '|' at beginning of match arms (RFC 1925) (accepted, match_beginning_vert, "1.25.0", Some(44101)), // Nested groups in `use` (RFC 2128) From 8be306840f89b92ee49d2c0fae2b189c45706b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 11 Feb 2018 02:27:21 +0300 Subject: [PATCH 11/18] added conversion from Rust feature to LLVM feature --- src/librustc_trans/attributes.rs | 5 ++- src/librustc_trans/llvm_util.rs | 72 +++++++++++++++++--------------- 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index 6c8088375c4b0..8309c91ab2573 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -142,7 +142,7 @@ pub fn provide(providers: &mut Providers) { assert_eq!(cnum, LOCAL_CRATE); Rc::new(llvm_util::target_feature_whitelist(tcx.sess) .iter() - .map(|c| c.to_str().unwrap().to_string()) + .map(|c| c.to_string()) .collect()) }; @@ -212,7 +212,8 @@ fn from_target_feature( let value = value.as_str(); for feature in value.split(',') { if whitelist.contains(feature) { - target_features.push(format!("+{}", feature)); + let llvm_feature = llvm_util::to_llvm_feature(feature); + target_features.push(format!("+{}", llvm_feature)); continue } diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 21def37e5e6e5..61eefb32e099a 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -79,45 +79,54 @@ unsafe fn configure_llvm(sess: &Session) { // detection code will walk past the end of the feature array, // leading to crashes. -const ARM_WHITELIST: &'static [&'static str] = &["neon\0", "v7\0", "vfp2\0", "vfp3\0", "vfp4\0"]; - -const AARCH64_WHITELIST: &'static [&'static str] = &["neon\0", "v7\0"]; - -const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bmi2\0", "sse\0", - "sse2\0", "sse3\0", "sse4.1\0", "sse4.2\0", - "ssse3\0", "tbm\0", "lzcnt\0", "popcnt\0", - "sse4a\0", "rdrnd\0", "rdseed\0", "fma\0", - "xsave\0", "xsaveopt\0", "xsavec\0", - "xsaves\0", "aes\0", "pclmul\0", - "avx512bw\0", "avx512cd\0", - "avx512dq\0", "avx512er\0", - "avx512f\0", "avx512ifma\0", - "avx512pf\0", "avx512vbmi\0", - "avx512vl\0", "avx512vpopcntdq\0", - "mmx\0", "fxsr\0"]; - -const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"]; - -const POWERPC_WHITELIST: &'static [&'static str] = &["altivec\0", - "power8-altivec\0", "power9-altivec\0", - "power8-vector\0", "power9-vector\0", - "vsx\0"]; - -const MIPS_WHITELIST: &'static [&'static str] = &["msa\0"]; +const ARM_WHITELIST: &'static [&'static str] = &["neon", "v7", "vfp2", "vfp3", "vfp4"]; + +const AARCH64_WHITELIST: &'static [&'static str] = &["neon", "v7"]; + +const X86_WHITELIST: &'static [&'static str] = &["avx", "avx2", "bmi", "bmi2", "sse", + "sse2", "sse3", "sse4.1", "sse4.2", + "ssse3", "tbm", "lzcnt", "popcnt", + "sse4a", "rdrnd", "rdseed", "fma", + "xsave", "xsaveopt", "xsavec", + "xsaves", "aes", "pclmulqdq", + "avx512bw", "avx512cd", + "avx512dq", "avx512er", + "avx512f", "avx512ifma", + "avx512pf", "avx512vbmi", + "avx512vl", "avx512vpopcntdq", + "mmx", "fxsr"]; + +const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx", "hvx-double"]; + +const POWERPC_WHITELIST: &'static [&'static str] = &["altivec", + "power8-altivec", "power9-altivec", + "power8-vector", "power9-vector", + "vsx"]; + +const MIPS_WHITELIST: &'static [&'static str] = &["msa"]; + +pub fn to_llvm_feature(s: &str) -> &str { + match s { + "pclmulqdq" => "pclmul", + s => s, + } +} pub fn target_features(sess: &Session) -> Vec { let whitelist = target_feature_whitelist(sess); let target_machine = create_target_machine(sess); let mut features = Vec::new(); - for feat in whitelist { - if unsafe { llvm::LLVMRustHasFeature(target_machine, feat.as_ptr()) } { - features.push(Symbol::intern(feat.to_str().unwrap())); + for feature in whitelist { + let llvm_feature = to_llvm_feature(feature); + let ptr = CString::new(llvm_feature).as_ptr(); + if unsafe { llvm::LLVMRustHasFeature(target_machine, ptr) } { + features.push(Symbol::intern(feature)); } } features } -pub fn target_feature_whitelist(sess: &Session) -> Vec<&CStr> { +pub fn target_feature_whitelist(sess: &Session) -> &'static [&'static str] { let whitelist = match &*sess.target.target.arch { "arm" => ARM_WHITELIST, "aarch64" => AARCH64_WHITELIST, @@ -126,10 +135,7 @@ pub fn target_feature_whitelist(sess: &Session) -> Vec<&CStr> { "mips" | "mips64" => MIPS_WHITELIST, "powerpc" | "powerpc64" => POWERPC_WHITELIST, _ => &[], - }; - whitelist.iter().map(|m| { - CStr::from_bytes_with_nul(m.as_bytes()).unwrap() - }).collect() + } } pub fn print_version() { From c97aa0911785fc1c1306b38e978093b3153666ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 11 Feb 2018 02:36:22 +0300 Subject: [PATCH 12/18] iterator instead loop --- src/librustc_trans/llvm_util.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 61eefb32e099a..8839129f3f88e 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -113,17 +113,15 @@ pub fn to_llvm_feature(s: &str) -> &str { } pub fn target_features(sess: &Session) -> Vec { - let whitelist = target_feature_whitelist(sess); let target_machine = create_target_machine(sess); - let mut features = Vec::new(); - for feature in whitelist { - let llvm_feature = to_llvm_feature(feature); - let ptr = CString::new(llvm_feature).as_ptr(); - if unsafe { llvm::LLVMRustHasFeature(target_machine, ptr) } { - features.push(Symbol::intern(feature)); - } - } - features + target_feature_whitelist(sess) + .iter() + .filter(|feature| { + let llvm_feature = to_llvm_feature(feature); + let ptr = CString::new(llvm_feature).as_ptr(); + unsafe { llvm::LLVMRustHasFeature(target_machine, ptr) } + }) + .map(Symbol::intern).collect() } pub fn target_feature_whitelist(sess: &Session) -> &'static [&'static str] { From 161e8ffda79d25ef7a570bf0c0d884201267c6cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 11 Feb 2018 00:56:24 +0100 Subject: [PATCH 13/18] typo: correct endianess to endianness (this also changes function names!) --- src/librustc_mir/interpret/memory.rs | 32 ++++++++++++++-------------- src/libstd/f32.rs | 2 +- src/libstd/f64.rs | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 3a28eae2d1c49..7cc4ba8489525 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -238,7 +238,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> { self.tcx.data_layout.pointer_size.bytes() } - pub fn endianess(&self) -> layout::Endian { + pub fn endianness(&self) -> layout::Endian { self.tcx.data_layout.endian } @@ -722,7 +722,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> { pub fn read_primval(&self, ptr: MemoryPointer, ptr_align: Align, size: u64, signed: bool) -> EvalResult<'tcx, PrimVal> { self.check_relocation_edges(ptr, size)?; // Make sure we don't read part of a pointer as a pointer - let endianess = self.endianess(); + let endianness = self.endianness(); let bytes = self.get_bytes_unchecked(ptr, size, ptr_align.min(self.int_align(size)))?; // Undef check happens *after* we established that the alignment is correct. // We must not return Ok() for unaligned pointers! @@ -731,9 +731,9 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> { } // Now we do the actual reading let bytes = if signed { - read_target_int(endianess, bytes).unwrap() as u128 + read_target_int(endianness, bytes).unwrap() as u128 } else { - read_target_uint(endianess, bytes).unwrap() + read_target_uint(endianness, bytes).unwrap() }; // See if we got a pointer if size != self.pointer_size() { @@ -756,7 +756,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> { } pub fn write_primval(&mut self, ptr: MemoryPointer, ptr_align: Align, val: PrimVal, size: u64, signed: bool) -> EvalResult<'tcx> { - let endianess = self.endianess(); + let endianness = self.endianness(); let bytes = match val { PrimVal::Ptr(val) => { @@ -788,9 +788,9 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> { let align = self.int_align(size); let dst = self.get_bytes_mut(ptr, size, ptr_align.min(align))?; if signed { - write_target_int(endianess, dst, bytes as i128).unwrap(); + write_target_int(endianness, dst, bytes as i128).unwrap(); } else { - write_target_uint(endianess, dst, bytes).unwrap(); + write_target_uint(endianness, dst, bytes).unwrap(); } } @@ -941,41 +941,41 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> { } //////////////////////////////////////////////////////////////////////////////// -// Methods to access integers in the target endianess +// Methods to access integers in the target endianness //////////////////////////////////////////////////////////////////////////////// fn write_target_uint( - endianess: layout::Endian, + endianness: layout::Endian, mut target: &mut [u8], data: u128, ) -> Result<(), io::Error> { let len = target.len(); - match endianess { + match endianness { layout::Endian::Little => target.write_uint128::(data, len), layout::Endian::Big => target.write_uint128::(data, len), } } fn write_target_int( - endianess: layout::Endian, + endianness: layout::Endian, mut target: &mut [u8], data: i128, ) -> Result<(), io::Error> { let len = target.len(); - match endianess { + match endianness { layout::Endian::Little => target.write_int128::(data, len), layout::Endian::Big => target.write_int128::(data, len), } } -fn read_target_uint(endianess: layout::Endian, mut source: &[u8]) -> Result { - match endianess { +fn read_target_uint(endianness: layout::Endian, mut source: &[u8]) -> Result { + match endianness { layout::Endian::Little => source.read_uint128::(source.len()), layout::Endian::Big => source.read_uint128::(source.len()), } } -fn read_target_int(endianess: layout::Endian, mut source: &[u8]) -> Result { - match endianess { +fn read_target_int(endianness: layout::Endian, mut source: &[u8]) -> Result { + match endianness { layout::Endian::Little => source.read_int128::(source.len()), layout::Endian::Big => source.read_int128::(source.len()), } diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index ecf68f29d6f1f..a760922115aef 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -1023,7 +1023,7 @@ impl f32 { /// This is currently identical to `transmute::(v)` on all platforms. /// It turns out this is incredibly portable, for two reasons: /// - /// * Floats and Ints have the same endianess on all supported platforms. + /// * Floats and Ints have the same endianness on all supported platforms. /// * IEEE-754 very precisely specifies the bit layout of floats. /// /// However there is one caveat: prior to the 2008 version of IEEE-754, how diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 29ba7d0dac635..6f34f176a9711 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -978,7 +978,7 @@ impl f64 { /// This is currently identical to `transmute::(v)` on all platforms. /// It turns out this is incredibly portable, for two reasons: /// - /// * Floats and Ints have the same endianess on all supported platforms. + /// * Floats and Ints have the same endianness on all supported platforms. /// * IEEE-754 very precisely specifies the bit layout of floats. /// /// However there is one caveat: prior to the 2008 version of IEEE-754, how From 7c6adb475abef794cc6b81f6a21094f3257ee37b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 11 Feb 2018 03:27:04 +0300 Subject: [PATCH 14/18] fixed errors --- src/librustc_trans/llvm_util.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 8839129f3f88e..1f921513fe628 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -14,7 +14,7 @@ use llvm; use rustc::session::Session; use rustc::session::config::PrintRequest; use libc::c_int; -use std::ffi::{CStr, CString}; +use std::ffi::CString; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Once; @@ -118,14 +118,14 @@ pub fn target_features(sess: &Session) -> Vec { .iter() .filter(|feature| { let llvm_feature = to_llvm_feature(feature); - let ptr = CString::new(llvm_feature).as_ptr(); + let ptr = CString::new(llvm_feature).unwrap().as_ptr(); unsafe { llvm::LLVMRustHasFeature(target_machine, ptr) } }) - .map(Symbol::intern).collect() + .map(|feature| Symbol::intern(feature)).collect() } pub fn target_feature_whitelist(sess: &Session) -> &'static [&'static str] { - let whitelist = match &*sess.target.target.arch { + match &*sess.target.target.arch { "arm" => ARM_WHITELIST, "aarch64" => AARCH64_WHITELIST, "x86" | "x86_64" => X86_WHITELIST, From 22b0489f80dae5242f19c4ce892b50d3685dbf82 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 10 Feb 2018 16:32:05 -0800 Subject: [PATCH 15/18] Add the emptiness condition to the docs; add a PartialOrd example with NAN --- src/libcore/ops/range.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 4e4d334752370..8a45444f1ab0c 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -60,7 +60,7 @@ impl fmt::Debug for RangeFull { /// (`start..end`). /// /// The `Range` `start..end` contains all values with `x >= start` and -/// `x < end`. +/// `x < end`. It is empty unless `start < end`. /// /// # Examples /// @@ -124,6 +124,17 @@ impl> Range { /// assert!( (3..3).is_empty()); /// assert!( (3..2).is_empty()); /// ``` + /// + /// The range is empty if either side is incomparable: + /// + /// ``` + /// #![feature(range_is_empty,inclusive_range_syntax)] + /// + /// use std::f32::NAN; + /// assert!(!(3.0..5.0).is_empty()); + /// assert!( (3.0..NAN).is_empty()); + /// assert!( (NAN..5.0).is_empty()); + /// ``` #[unstable(feature = "range_is_empty", reason = "recently added", issue = "48111")] pub fn is_empty(&self) -> bool { !(self.start < self.end) @@ -260,7 +271,7 @@ impl> RangeTo { /// An range bounded inclusively below and above (`start..=end`). /// /// The `RangeInclusive` `start..=end` contains all values with `x >= start` -/// and `x <= end`. +/// and `x <= end`. It is empty unless `start <= end`. /// /// This iterator is [fused], but the specific values of `start` and `end` after /// iteration has finished are **unspecified** other than that [`.is_empty()`] @@ -337,6 +348,17 @@ impl> RangeInclusive { /// assert!( (3..=2).is_empty()); /// ``` /// + /// The range is empty if either side is incomparable: + /// + /// ``` + /// #![feature(range_is_empty,inclusive_range_syntax)] + /// + /// use std::f32::NAN; + /// assert!(!(3.0..=5.0).is_empty()); + /// assert!( (3.0..=NAN).is_empty()); + /// assert!( (NAN..=5.0).is_empty()); + /// ``` + /// /// This method returns `true` after iteration has finished: /// /// ``` From bf69b0feed33f40ddbef2940b9a3d99845982153 Mon Sep 17 00:00:00 2001 From: kennytm Date: Fri, 26 Jan 2018 03:14:20 +0800 Subject: [PATCH 16/18] Upgrade the Travis CI macOS images for testing from Xcode 8.3 to 9.2. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1007aad925d96..280da05699506 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ matrix: NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1 os: osx - osx_image: xcode8.3 + osx_image: xcode9.2 if: branch = auto - env: > @@ -70,7 +70,7 @@ matrix: NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1 os: osx - osx_image: xcode8.3 + osx_image: xcode9.2 if: branch = auto # OSX builders producing releases. These do not run the full test suite and From c2a31dee835c2312a9e527b1f9ea1b77c24beeab Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sun, 11 Feb 2018 15:57:07 +0300 Subject: [PATCH 17/18] Dangling pointer fix --- src/librustc_trans/llvm_util.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 1f921513fe628..b25562252e72e 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -118,8 +118,8 @@ pub fn target_features(sess: &Session) -> Vec { .iter() .filter(|feature| { let llvm_feature = to_llvm_feature(feature); - let ptr = CString::new(llvm_feature).unwrap().as_ptr(); - unsafe { llvm::LLVMRustHasFeature(target_machine, ptr) } + let cstr = CString::new(llvm_feature).unwrap(); + unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) } }) .map(|feature| Symbol::intern(feature)).collect() } From bd426f1d69ec8371d86e06382e96e9ed842f3933 Mon Sep 17 00:00:00 2001 From: Jason Schein Date: Sun, 11 Feb 2018 17:54:44 -0800 Subject: [PATCH 18/18] Update ops range example to avoid confusion between indexes and values. --- src/libcore/ops/range.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 3f573f7c7eb69..a80699c0f5afd 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -68,11 +68,11 @@ impl fmt::Debug for RangeFull { /// assert_eq!((3..5), std::ops::Range { start: 3, end: 5 }); /// assert_eq!(3 + 4 + 5, (3..6).sum()); /// -/// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ .. ], [0,1,2,3]); -/// assert_eq!(arr[ ..3], [0,1,2 ]); -/// assert_eq!(arr[1.. ], [ 1,2,3]); -/// assert_eq!(arr[1..3], [ 1,2 ]); // Range +/// let arr = ['a', 'b', 'c', 'd']; +/// assert_eq!(arr[ .. ], ['a', 'b', 'c', 'd']); +/// assert_eq!(arr[ ..3], ['a', 'b', 'c', ]); +/// assert_eq!(arr[1.. ], [ 'b', 'c', 'd']); +/// assert_eq!(arr[1..3], [ 'b', 'c' ]); // Range /// ``` #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")]