Skip to content

Commit a6bc43e

Browse files
committed
Auto merge of rust-lang#86417 - m-ou-se:rollup-vo2y1rz, r=m-ou-se
Rollup of 6 pull requests Successful merges: - rust-lang#85925 (Linear interpolation) - rust-lang#86202 (Specialize `io::Bytes::size_hint` for more types) - rust-lang#86357 (Rely on libc for correct integer types in os/unix/net/ancillary.rs.) - rust-lang#86388 (Make `s` pre-interned) - rust-lang#86401 (Fix ICE when using `#[doc(keyword = "...")]` on non-items) - rust-lang#86405 (Add incr-comp note for 1.53.0 relnotes) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 149f483 + 4ec05e0 commit a6bc43e

File tree

16 files changed

+320
-112
lines changed

16 files changed

+320
-112
lines changed

RELEASES.md

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ Compatibility Notes
113113
In particular, this was known to be a problem in the `lexical-core` crate,
114114
but they have published fixes for semantic versions 0.4 through 0.7. To
115115
update this dependency alone, use `cargo update -p lexical-core`.
116+
- Incremental compilation remains off by default, unless one uses the `RUSTC_FORCE_INCREMENTAL=1` environment variable added in 1.52.1.
116117

117118
Internal Only
118119
-------------

compiler/rustc_builtin_macros/src/deriving/encodable.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,7 @@ pub fn expand_deriving_rustc_encodable(
124124
explicit_self: borrowed_explicit_self(),
125125
args: vec![(
126126
Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)),
127-
// FIXME: we could use `sym::s` here, but making `s` a static
128-
// symbol changes the symbol index ordering in a way that makes
129-
// ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs
130-
// fail. The linting code should be fixed so that its output
131-
// does not depend on the symbol index ordering.
132-
Symbol::intern("s"),
127+
sym::s,
133128
)],
134129
ret_ty: Literal(Path::new_(
135130
pathvec_std!(result::Result),

compiler/rustc_passes/src/check_attr.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -525,8 +525,11 @@ impl CheckAttrVisitor<'tcx> {
525525
self.doc_attr_str_error(meta, "keyword");
526526
return false;
527527
}
528-
match self.tcx.hir().expect_item(hir_id).kind {
529-
ItemKind::Mod(ref module) => {
528+
match self.tcx.hir().find(hir_id).and_then(|node| match node {
529+
hir::Node::Item(item) => Some(&item.kind),
530+
_ => None,
531+
}) {
532+
Some(ItemKind::Mod(ref module)) => {
530533
if !module.item_ids.is_empty() {
531534
self.tcx
532535
.sess

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1062,6 +1062,7 @@ symbols! {
10621062
rustdoc,
10631063
rustfmt,
10641064
rvalue_static_promotion,
1065+
s,
10651066
sanitize,
10661067
sanitizer_runtime,
10671068
saturating_add,

library/std/src/f32.rs

+36
Original file line numberDiff line numberDiff line change
@@ -876,4 +876,40 @@ impl f32 {
876876
pub fn atanh(self) -> f32 {
877877
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
878878
}
879+
880+
/// Linear interpolation between `start` and `end`.
881+
///
882+
/// This enables linear interpolation between `start` and `end`, where start is represented by
883+
/// `self == 0.0` and `end` is represented by `self == 1.0`. This is the basis of all
884+
/// "transition", "easing", or "step" functions; if you change `self` from 0.0 to 1.0
885+
/// at a given rate, the result will change from `start` to `end` at a similar rate.
886+
///
887+
/// Values below 0.0 or above 1.0 are allowed, allowing you to extrapolate values outside the
888+
/// range from `start` to `end`. This also is useful for transition functions which might
889+
/// move slightly past the end or start for a desired effect. Mathematically, the values
890+
/// returned are equivalent to `start + self * (end - start)`, although we make a few specific
891+
/// guarantees that are useful specifically to linear interpolation.
892+
///
893+
/// These guarantees are:
894+
///
895+
/// * If `start` and `end` are [finite], the value at 0.0 is always `start` and the
896+
/// value at 1.0 is always `end`. (exactness)
897+
/// * If `start` and `end` are [finite], the values will always move in the direction from
898+
/// `start` to `end` (monotonicity)
899+
/// * If `self` is [finite] and `start == end`, the value at any point will always be
900+
/// `start == end`. (consistency)
901+
///
902+
/// [finite]: #method.is_finite
903+
#[must_use = "method returns a new number and does not mutate the original value"]
904+
#[unstable(feature = "float_interpolation", issue = "86269")]
905+
pub fn lerp(self, start: f32, end: f32) -> f32 {
906+
// consistent
907+
if start == end {
908+
start
909+
910+
// exact/monotonic
911+
} else {
912+
self.mul_add(end, (-self).mul_add(start, start))
913+
}
914+
}
879915
}

library/std/src/f32/tests.rs

+63
Original file line numberDiff line numberDiff line change
@@ -757,3 +757,66 @@ fn test_total_cmp() {
757757
assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::INFINITY));
758758
assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan()));
759759
}
760+
761+
#[test]
762+
fn test_lerp_exact() {
763+
// simple values
764+
assert_eq!(f32::lerp(0.0, 2.0, 4.0), 2.0);
765+
assert_eq!(f32::lerp(1.0, 2.0, 4.0), 4.0);
766+
767+
// boundary values
768+
assert_eq!(f32::lerp(0.0, f32::MIN, f32::MAX), f32::MIN);
769+
assert_eq!(f32::lerp(1.0, f32::MIN, f32::MAX), f32::MAX);
770+
}
771+
772+
#[test]
773+
fn test_lerp_consistent() {
774+
assert_eq!(f32::lerp(f32::MAX, f32::MIN, f32::MIN), f32::MIN);
775+
assert_eq!(f32::lerp(f32::MIN, f32::MAX, f32::MAX), f32::MAX);
776+
777+
// as long as t is finite, a/b can be infinite
778+
assert_eq!(f32::lerp(f32::MAX, f32::NEG_INFINITY, f32::NEG_INFINITY), f32::NEG_INFINITY);
779+
assert_eq!(f32::lerp(f32::MIN, f32::INFINITY, f32::INFINITY), f32::INFINITY);
780+
}
781+
782+
#[test]
783+
fn test_lerp_nan_infinite() {
784+
// non-finite t is not NaN if a/b different
785+
assert!(!f32::lerp(f32::INFINITY, f32::MIN, f32::MAX).is_nan());
786+
assert!(!f32::lerp(f32::NEG_INFINITY, f32::MIN, f32::MAX).is_nan());
787+
}
788+
789+
#[test]
790+
fn test_lerp_values() {
791+
// just a few basic values
792+
assert_eq!(f32::lerp(0.25, 1.0, 2.0), 1.25);
793+
assert_eq!(f32::lerp(0.50, 1.0, 2.0), 1.50);
794+
assert_eq!(f32::lerp(0.75, 1.0, 2.0), 1.75);
795+
}
796+
797+
#[test]
798+
fn test_lerp_monotonic() {
799+
// near 0
800+
let below_zero = f32::lerp(-f32::EPSILON, f32::MIN, f32::MAX);
801+
let zero = f32::lerp(0.0, f32::MIN, f32::MAX);
802+
let above_zero = f32::lerp(f32::EPSILON, f32::MIN, f32::MAX);
803+
assert!(below_zero <= zero);
804+
assert!(zero <= above_zero);
805+
assert!(below_zero <= above_zero);
806+
807+
// near 0.5
808+
let below_half = f32::lerp(0.5 - f32::EPSILON, f32::MIN, f32::MAX);
809+
let half = f32::lerp(0.5, f32::MIN, f32::MAX);
810+
let above_half = f32::lerp(0.5 + f32::EPSILON, f32::MIN, f32::MAX);
811+
assert!(below_half <= half);
812+
assert!(half <= above_half);
813+
assert!(below_half <= above_half);
814+
815+
// near 1
816+
let below_one = f32::lerp(1.0 - f32::EPSILON, f32::MIN, f32::MAX);
817+
let one = f32::lerp(1.0, f32::MIN, f32::MAX);
818+
let above_one = f32::lerp(1.0 + f32::EPSILON, f32::MIN, f32::MAX);
819+
assert!(below_one <= one);
820+
assert!(one <= above_one);
821+
assert!(below_one <= above_one);
822+
}

library/std/src/f64.rs

+36
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,42 @@ impl f64 {
879879
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
880880
}
881881

882+
/// Linear interpolation between `start` and `end`.
883+
///
884+
/// This enables linear interpolation between `start` and `end`, where start is represented by
885+
/// `self == 0.0` and `end` is represented by `self == 1.0`. This is the basis of all
886+
/// "transition", "easing", or "step" functions; if you change `self` from 0.0 to 1.0
887+
/// at a given rate, the result will change from `start` to `end` at a similar rate.
888+
///
889+
/// Values below 0.0 or above 1.0 are allowed, allowing you to extrapolate values outside the
890+
/// range from `start` to `end`. This also is useful for transition functions which might
891+
/// move slightly past the end or start for a desired effect. Mathematically, the values
892+
/// returned are equivalent to `start + self * (end - start)`, although we make a few specific
893+
/// guarantees that are useful specifically to linear interpolation.
894+
///
895+
/// These guarantees are:
896+
///
897+
/// * If `start` and `end` are [finite], the value at 0.0 is always `start` and the
898+
/// value at 1.0 is always `end`. (exactness)
899+
/// * If `start` and `end` are [finite], the values will always move in the direction from
900+
/// `start` to `end` (monotonicity)
901+
/// * If `self` is [finite] and `start == end`, the value at any point will always be
902+
/// `start == end`. (consistency)
903+
///
904+
/// [finite]: #method.is_finite
905+
#[must_use = "method returns a new number and does not mutate the original value"]
906+
#[unstable(feature = "float_interpolation", issue = "86269")]
907+
pub fn lerp(self, start: f64, end: f64) -> f64 {
908+
// consistent
909+
if start == end {
910+
start
911+
912+
// exact/monotonic
913+
} else {
914+
self.mul_add(end, (-self).mul_add(start, start))
915+
}
916+
}
917+
882918
// Solaris/Illumos requires a wrapper around log, log2, and log10 functions
883919
// because of their non-standard behavior (e.g., log(-n) returns -Inf instead
884920
// of expected NaN).

library/std/src/f64/tests.rs

+55
Original file line numberDiff line numberDiff line change
@@ -753,3 +753,58 @@ fn test_total_cmp() {
753753
assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::INFINITY));
754754
assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan()));
755755
}
756+
757+
#[test]
758+
fn test_lerp_exact() {
759+
// simple values
760+
assert_eq!(f64::lerp(0.0, 2.0, 4.0), 2.0);
761+
assert_eq!(f64::lerp(1.0, 2.0, 4.0), 4.0);
762+
763+
// boundary values
764+
assert_eq!(f64::lerp(0.0, f64::MIN, f64::MAX), f64::MIN);
765+
assert_eq!(f64::lerp(1.0, f64::MIN, f64::MAX), f64::MAX);
766+
}
767+
768+
#[test]
769+
fn test_lerp_consistent() {
770+
assert_eq!(f64::lerp(f64::MAX, f64::MIN, f64::MIN), f64::MIN);
771+
assert_eq!(f64::lerp(f64::MIN, f64::MAX, f64::MAX), f64::MAX);
772+
773+
// as long as t is finite, a/b can be infinite
774+
assert_eq!(f64::lerp(f64::MAX, f64::NEG_INFINITY, f64::NEG_INFINITY), f64::NEG_INFINITY);
775+
assert_eq!(f64::lerp(f64::MIN, f64::INFINITY, f64::INFINITY), f64::INFINITY);
776+
}
777+
778+
#[test]
779+
fn test_lerp_nan_infinite() {
780+
// non-finite t is not NaN if a/b different
781+
assert!(!f64::lerp(f64::INFINITY, f64::MIN, f64::MAX).is_nan());
782+
assert!(!f64::lerp(f64::NEG_INFINITY, f64::MIN, f64::MAX).is_nan());
783+
}
784+
785+
#[test]
786+
fn test_lerp_values() {
787+
// just a few basic values
788+
assert_eq!(f64::lerp(0.25, 1.0, 2.0), 1.25);
789+
assert_eq!(f64::lerp(0.50, 1.0, 2.0), 1.50);
790+
assert_eq!(f64::lerp(0.75, 1.0, 2.0), 1.75);
791+
}
792+
793+
#[test]
794+
fn test_lerp_monotonic() {
795+
// near 0
796+
let below_zero = f64::lerp(-f64::EPSILON, f64::MIN, f64::MAX);
797+
let zero = f64::lerp(0.0, f64::MIN, f64::MAX);
798+
let above_zero = f64::lerp(f64::EPSILON, f64::MIN, f64::MAX);
799+
assert!(below_zero <= zero);
800+
assert!(zero <= above_zero);
801+
assert!(below_zero <= above_zero);
802+
803+
// near 1
804+
let below_one = f64::lerp(1.0 - f64::EPSILON, f64::MIN, f64::MAX);
805+
let one = f64::lerp(1.0, f64::MIN, f64::MAX);
806+
let above_one = f64::lerp(1.0 + f64::EPSILON, f64::MIN, f64::MAX);
807+
assert!(below_one <= one);
808+
assert!(one <= above_one);
809+
assert!(below_one <= above_one);
810+
}

library/std/src/io/buffered/bufreader.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,13 @@ impl<R: Seek> Seek for BufReader<R> {
438438
}
439439

440440
impl<T> SizeHint for BufReader<T> {
441+
#[inline]
441442
fn lower_bound(&self) -> usize {
442-
self.buffer().len()
443+
SizeHint::lower_bound(self.get_ref()) + self.buffer().len()
444+
}
445+
446+
#[inline]
447+
fn upper_bound(&self) -> Option<usize> {
448+
SizeHint::upper_bound(self.get_ref()).and_then(|up| self.buffer().len().checked_add(up))
443449
}
444450
}

library/std/src/io/mod.rs

+57-1
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@
252252
mod tests;
253253

254254
use crate::cmp;
255+
use crate::convert::TryInto;
255256
use crate::fmt;
256257
use crate::mem::replace;
257258
use crate::ops::{Deref, DerefMut};
@@ -2342,13 +2343,15 @@ impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> {
23422343
}
23432344

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

2351+
#[inline]
23492352
fn upper_bound(&self) -> Option<usize> {
23502353
match (SizeHint::upper_bound(&self.first), SizeHint::upper_bound(&self.second)) {
2351-
(Some(first), Some(second)) => Some(first + second),
2354+
(Some(first), Some(second)) => first.checked_add(second),
23522355
_ => None,
23532356
}
23542357
}
@@ -2553,6 +2556,21 @@ impl<T: BufRead> BufRead for Take<T> {
25532556
}
25542557
}
25552558

2559+
impl<T> SizeHint for Take<T> {
2560+
#[inline]
2561+
fn lower_bound(&self) -> usize {
2562+
cmp::min(SizeHint::lower_bound(&self.inner) as u64, self.limit) as usize
2563+
}
2564+
2565+
#[inline]
2566+
fn upper_bound(&self) -> Option<usize> {
2567+
match SizeHint::upper_bound(&self.inner) {
2568+
Some(upper_bound) => Some(cmp::min(upper_bound as u64, self.limit) as usize),
2569+
None => self.limit.try_into().ok(),
2570+
}
2571+
}
2572+
}
2573+
25562574
/// An iterator over `u8` values of a reader.
25572575
///
25582576
/// This struct is generally created by calling [`bytes`] on a reader.
@@ -2597,15 +2615,53 @@ trait SizeHint {
25972615
}
25982616

25992617
impl<T> SizeHint for T {
2618+
#[inline]
26002619
default fn lower_bound(&self) -> usize {
26012620
0
26022621
}
26032622

2623+
#[inline]
26042624
default fn upper_bound(&self) -> Option<usize> {
26052625
None
26062626
}
26072627
}
26082628

2629+
impl<T> SizeHint for &mut T {
2630+
#[inline]
2631+
fn lower_bound(&self) -> usize {
2632+
SizeHint::lower_bound(*self)
2633+
}
2634+
2635+
#[inline]
2636+
fn upper_bound(&self) -> Option<usize> {
2637+
SizeHint::upper_bound(*self)
2638+
}
2639+
}
2640+
2641+
impl<T> SizeHint for Box<T> {
2642+
#[inline]
2643+
fn lower_bound(&self) -> usize {
2644+
SizeHint::lower_bound(&**self)
2645+
}
2646+
2647+
#[inline]
2648+
fn upper_bound(&self) -> Option<usize> {
2649+
SizeHint::upper_bound(&**self)
2650+
}
2651+
}
2652+
2653+
impl SizeHint for &[u8] {
2654+
#[inline]
2655+
fn lower_bound(&self) -> usize {
2656+
self.len()
2657+
}
2658+
2659+
#[inline]
2660+
fn upper_bound(&self) -> Option<usize> {
2661+
Some(self.len())
2662+
}
2663+
}
2664+
26092665
/// An iterator over the contents of an instance of `BufRead` split on a
26102666
/// particular byte.
26112667
///

0 commit comments

Comments
 (0)