Skip to content

Commit

Permalink
Auto merge of #86417 - m-ou-se:rollup-vo2y1rz, r=m-ou-se
Browse files Browse the repository at this point in the history
Rollup of 6 pull requests

Successful merges:

 - #85925 (Linear interpolation)
 - #86202 (Specialize `io::Bytes::size_hint` for more types)
 - #86357 (Rely on libc for correct integer types in os/unix/net/ancillary.rs.)
 - #86388 (Make `s` pre-interned)
 - #86401 (Fix ICE when using `#[doc(keyword = "...")]` on non-items)
 - #86405 (Add incr-comp note for 1.53.0 relnotes)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jun 17, 2021
2 parents 149f483 + 4ec05e0 commit a6bc43e
Show file tree
Hide file tree
Showing 16 changed files with 320 additions and 112 deletions.
1 change: 1 addition & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ Compatibility Notes
In particular, this was known to be a problem in the `lexical-core` crate,
but they have published fixes for semantic versions 0.4 through 0.7. To
update this dependency alone, use `cargo update -p lexical-core`.
- Incremental compilation remains off by default, unless one uses the `RUSTC_FORCE_INCREMENTAL=1` environment variable added in 1.52.1.

Internal Only
-------------
Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_builtin_macros/src/deriving/encodable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,7 @@ pub fn expand_deriving_rustc_encodable(
explicit_self: borrowed_explicit_self(),
args: vec![(
Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)),
// FIXME: we could use `sym::s` here, but making `s` a static
// symbol changes the symbol index ordering in a way that makes
// ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs
// fail. The linting code should be fixed so that its output
// does not depend on the symbol index ordering.
Symbol::intern("s"),
sym::s,
)],
ret_ty: Literal(Path::new_(
pathvec_std!(result::Result),
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,11 @@ impl CheckAttrVisitor<'tcx> {
self.doc_attr_str_error(meta, "keyword");
return false;
}
match self.tcx.hir().expect_item(hir_id).kind {
ItemKind::Mod(ref module) => {
match self.tcx.hir().find(hir_id).and_then(|node| match node {
hir::Node::Item(item) => Some(&item.kind),
_ => None,
}) {
Some(ItemKind::Mod(ref module)) => {
if !module.item_ids.is_empty() {
self.tcx
.sess
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,7 @@ symbols! {
rustdoc,
rustfmt,
rvalue_static_promotion,
s,
sanitize,
sanitizer_runtime,
saturating_add,
Expand Down
36 changes: 36 additions & 0 deletions library/std/src/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -876,4 +876,40 @@ impl f32 {
pub fn atanh(self) -> f32 {
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
}

/// Linear interpolation between `start` and `end`.
///
/// This enables linear interpolation between `start` and `end`, where start is represented by
/// `self == 0.0` and `end` is represented by `self == 1.0`. This is the basis of all
/// "transition", "easing", or "step" functions; if you change `self` from 0.0 to 1.0
/// at a given rate, the result will change from `start` to `end` at a similar rate.
///
/// Values below 0.0 or above 1.0 are allowed, allowing you to extrapolate values outside the
/// range from `start` to `end`. This also is useful for transition functions which might
/// move slightly past the end or start for a desired effect. Mathematically, the values
/// returned are equivalent to `start + self * (end - start)`, although we make a few specific
/// guarantees that are useful specifically to linear interpolation.
///
/// These guarantees are:
///
/// * If `start` and `end` are [finite], the value at 0.0 is always `start` and the
/// value at 1.0 is always `end`. (exactness)
/// * If `start` and `end` are [finite], the values will always move in the direction from
/// `start` to `end` (monotonicity)
/// * If `self` is [finite] and `start == end`, the value at any point will always be
/// `start == end`. (consistency)
///
/// [finite]: #method.is_finite
#[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_interpolation", issue = "86269")]
pub fn lerp(self, start: f32, end: f32) -> f32 {
// consistent
if start == end {
start

// exact/monotonic
} else {
self.mul_add(end, (-self).mul_add(start, start))
}
}
}
63 changes: 63 additions & 0 deletions library/std/src/f32/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,3 +757,66 @@ fn test_total_cmp() {
assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::INFINITY));
assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan()));
}

#[test]
fn test_lerp_exact() {
// simple values
assert_eq!(f32::lerp(0.0, 2.0, 4.0), 2.0);
assert_eq!(f32::lerp(1.0, 2.0, 4.0), 4.0);

// boundary values
assert_eq!(f32::lerp(0.0, f32::MIN, f32::MAX), f32::MIN);
assert_eq!(f32::lerp(1.0, f32::MIN, f32::MAX), f32::MAX);
}

#[test]
fn test_lerp_consistent() {
assert_eq!(f32::lerp(f32::MAX, f32::MIN, f32::MIN), f32::MIN);
assert_eq!(f32::lerp(f32::MIN, f32::MAX, f32::MAX), f32::MAX);

// as long as t is finite, a/b can be infinite
assert_eq!(f32::lerp(f32::MAX, f32::NEG_INFINITY, f32::NEG_INFINITY), f32::NEG_INFINITY);
assert_eq!(f32::lerp(f32::MIN, f32::INFINITY, f32::INFINITY), f32::INFINITY);
}

#[test]
fn test_lerp_nan_infinite() {
// non-finite t is not NaN if a/b different
assert!(!f32::lerp(f32::INFINITY, f32::MIN, f32::MAX).is_nan());
assert!(!f32::lerp(f32::NEG_INFINITY, f32::MIN, f32::MAX).is_nan());
}

#[test]
fn test_lerp_values() {
// just a few basic values
assert_eq!(f32::lerp(0.25, 1.0, 2.0), 1.25);
assert_eq!(f32::lerp(0.50, 1.0, 2.0), 1.50);
assert_eq!(f32::lerp(0.75, 1.0, 2.0), 1.75);
}

#[test]
fn test_lerp_monotonic() {
// near 0
let below_zero = f32::lerp(-f32::EPSILON, f32::MIN, f32::MAX);
let zero = f32::lerp(0.0, f32::MIN, f32::MAX);
let above_zero = f32::lerp(f32::EPSILON, f32::MIN, f32::MAX);
assert!(below_zero <= zero);
assert!(zero <= above_zero);
assert!(below_zero <= above_zero);

// near 0.5
let below_half = f32::lerp(0.5 - f32::EPSILON, f32::MIN, f32::MAX);
let half = f32::lerp(0.5, f32::MIN, f32::MAX);
let above_half = f32::lerp(0.5 + f32::EPSILON, f32::MIN, f32::MAX);
assert!(below_half <= half);
assert!(half <= above_half);
assert!(below_half <= above_half);

// near 1
let below_one = f32::lerp(1.0 - f32::EPSILON, f32::MIN, f32::MAX);
let one = f32::lerp(1.0, f32::MIN, f32::MAX);
let above_one = f32::lerp(1.0 + f32::EPSILON, f32::MIN, f32::MAX);
assert!(below_one <= one);
assert!(one <= above_one);
assert!(below_one <= above_one);
}
36 changes: 36 additions & 0 deletions library/std/src/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,42 @@ impl f64 {
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
}

/// Linear interpolation between `start` and `end`.
///
/// This enables linear interpolation between `start` and `end`, where start is represented by
/// `self == 0.0` and `end` is represented by `self == 1.0`. This is the basis of all
/// "transition", "easing", or "step" functions; if you change `self` from 0.0 to 1.0
/// at a given rate, the result will change from `start` to `end` at a similar rate.
///
/// Values below 0.0 or above 1.0 are allowed, allowing you to extrapolate values outside the
/// range from `start` to `end`. This also is useful for transition functions which might
/// move slightly past the end or start for a desired effect. Mathematically, the values
/// returned are equivalent to `start + self * (end - start)`, although we make a few specific
/// guarantees that are useful specifically to linear interpolation.
///
/// These guarantees are:
///
/// * If `start` and `end` are [finite], the value at 0.0 is always `start` and the
/// value at 1.0 is always `end`. (exactness)
/// * If `start` and `end` are [finite], the values will always move in the direction from
/// `start` to `end` (monotonicity)
/// * If `self` is [finite] and `start == end`, the value at any point will always be
/// `start == end`. (consistency)
///
/// [finite]: #method.is_finite
#[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_interpolation", issue = "86269")]
pub fn lerp(self, start: f64, end: f64) -> f64 {
// consistent
if start == end {
start

// exact/monotonic
} else {
self.mul_add(end, (-self).mul_add(start, start))
}
}

// Solaris/Illumos requires a wrapper around log, log2, and log10 functions
// because of their non-standard behavior (e.g., log(-n) returns -Inf instead
// of expected NaN).
Expand Down
55 changes: 55 additions & 0 deletions library/std/src/f64/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -753,3 +753,58 @@ fn test_total_cmp() {
assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::INFINITY));
assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan()));
}

#[test]
fn test_lerp_exact() {
// simple values
assert_eq!(f64::lerp(0.0, 2.0, 4.0), 2.0);
assert_eq!(f64::lerp(1.0, 2.0, 4.0), 4.0);

// boundary values
assert_eq!(f64::lerp(0.0, f64::MIN, f64::MAX), f64::MIN);
assert_eq!(f64::lerp(1.0, f64::MIN, f64::MAX), f64::MAX);
}

#[test]
fn test_lerp_consistent() {
assert_eq!(f64::lerp(f64::MAX, f64::MIN, f64::MIN), f64::MIN);
assert_eq!(f64::lerp(f64::MIN, f64::MAX, f64::MAX), f64::MAX);

// as long as t is finite, a/b can be infinite
assert_eq!(f64::lerp(f64::MAX, f64::NEG_INFINITY, f64::NEG_INFINITY), f64::NEG_INFINITY);
assert_eq!(f64::lerp(f64::MIN, f64::INFINITY, f64::INFINITY), f64::INFINITY);
}

#[test]
fn test_lerp_nan_infinite() {
// non-finite t is not NaN if a/b different
assert!(!f64::lerp(f64::INFINITY, f64::MIN, f64::MAX).is_nan());
assert!(!f64::lerp(f64::NEG_INFINITY, f64::MIN, f64::MAX).is_nan());
}

#[test]
fn test_lerp_values() {
// just a few basic values
assert_eq!(f64::lerp(0.25, 1.0, 2.0), 1.25);
assert_eq!(f64::lerp(0.50, 1.0, 2.0), 1.50);
assert_eq!(f64::lerp(0.75, 1.0, 2.0), 1.75);
}

#[test]
fn test_lerp_monotonic() {
// near 0
let below_zero = f64::lerp(-f64::EPSILON, f64::MIN, f64::MAX);
let zero = f64::lerp(0.0, f64::MIN, f64::MAX);
let above_zero = f64::lerp(f64::EPSILON, f64::MIN, f64::MAX);
assert!(below_zero <= zero);
assert!(zero <= above_zero);
assert!(below_zero <= above_zero);

// near 1
let below_one = f64::lerp(1.0 - f64::EPSILON, f64::MIN, f64::MAX);
let one = f64::lerp(1.0, f64::MIN, f64::MAX);
let above_one = f64::lerp(1.0 + f64::EPSILON, f64::MIN, f64::MAX);
assert!(below_one <= one);
assert!(one <= above_one);
assert!(below_one <= above_one);
}
8 changes: 7 additions & 1 deletion library/std/src/io/buffered/bufreader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,13 @@ impl<R: Seek> Seek for BufReader<R> {
}

impl<T> SizeHint for BufReader<T> {
#[inline]
fn lower_bound(&self) -> usize {
self.buffer().len()
SizeHint::lower_bound(self.get_ref()) + self.buffer().len()
}

#[inline]
fn upper_bound(&self) -> Option<usize> {
SizeHint::upper_bound(self.get_ref()).and_then(|up| self.buffer().len().checked_add(up))
}
}
58 changes: 57 additions & 1 deletion library/std/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@
mod tests;

use crate::cmp;
use crate::convert::TryInto;
use crate::fmt;
use crate::mem::replace;
use crate::ops::{Deref, DerefMut};
Expand Down Expand Up @@ -2342,13 +2343,15 @@ impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> {
}

impl<T, U> SizeHint for Chain<T, U> {
#[inline]
fn lower_bound(&self) -> usize {
SizeHint::lower_bound(&self.first) + SizeHint::lower_bound(&self.second)
}

#[inline]
fn upper_bound(&self) -> Option<usize> {
match (SizeHint::upper_bound(&self.first), SizeHint::upper_bound(&self.second)) {
(Some(first), Some(second)) => Some(first + second),
(Some(first), Some(second)) => first.checked_add(second),
_ => None,
}
}
Expand Down Expand Up @@ -2553,6 +2556,21 @@ impl<T: BufRead> BufRead for Take<T> {
}
}

impl<T> SizeHint for Take<T> {
#[inline]
fn lower_bound(&self) -> usize {
cmp::min(SizeHint::lower_bound(&self.inner) as u64, self.limit) as usize
}

#[inline]
fn upper_bound(&self) -> Option<usize> {
match SizeHint::upper_bound(&self.inner) {
Some(upper_bound) => Some(cmp::min(upper_bound as u64, self.limit) as usize),
None => self.limit.try_into().ok(),
}
}
}

/// An iterator over `u8` values of a reader.
///
/// This struct is generally created by calling [`bytes`] on a reader.
Expand Down Expand Up @@ -2597,15 +2615,53 @@ trait SizeHint {
}

impl<T> SizeHint for T {
#[inline]
default fn lower_bound(&self) -> usize {
0
}

#[inline]
default fn upper_bound(&self) -> Option<usize> {
None
}
}

impl<T> SizeHint for &mut T {
#[inline]
fn lower_bound(&self) -> usize {
SizeHint::lower_bound(*self)
}

#[inline]
fn upper_bound(&self) -> Option<usize> {
SizeHint::upper_bound(*self)
}
}

impl<T> SizeHint for Box<T> {
#[inline]
fn lower_bound(&self) -> usize {
SizeHint::lower_bound(&**self)
}

#[inline]
fn upper_bound(&self) -> Option<usize> {
SizeHint::upper_bound(&**self)
}
}

impl SizeHint for &[u8] {
#[inline]
fn lower_bound(&self) -> usize {
self.len()
}

#[inline]
fn upper_bound(&self) -> Option<usize> {
Some(self.len())
}
}

/// An iterator over the contents of an instance of `BufRead` split on a
/// particular byte.
///
Expand Down
Loading

0 comments on commit a6bc43e

Please sign in to comment.