Skip to content

Commit 93711d0

Browse files
committed
Auto merge of #69309 - Dylan-DPC:rollup-gjdqx7l, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #68705 (Add LinkedList::remove()) - #68945 (Stabilize Once::is_completed) - #68978 (Make integer exponentiation methods unstably const) - #69266 (Fix race condition when allocating source files in SourceMap) - #69287 (Clean up E0317 explanation) Failed merges: r? @ghost
2 parents 6af388b + 941ce1a commit 93711d0

File tree

8 files changed

+207
-55
lines changed

8 files changed

+207
-55
lines changed

src/liballoc/collections/linked_list.rs

+46
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,52 @@ impl<T> LinkedList<T> {
878878
unsafe { self.split_off_after_node(split_node, at) }
879879
}
880880

881+
/// Removes the element at the given index and returns it.
882+
///
883+
/// This operation should compute in O(n) time.
884+
///
885+
/// # Panics
886+
/// Panics if at >= len
887+
///
888+
/// # Examples
889+
///
890+
/// ```
891+
/// #![feature(linked_list_remove)]
892+
/// use std::collections::LinkedList;
893+
///
894+
/// let mut d = LinkedList::new();
895+
///
896+
/// d.push_front(1);
897+
/// d.push_front(2);
898+
/// d.push_front(3);
899+
///
900+
/// assert_eq!(d.remove(1), 2);
901+
/// assert_eq!(d.remove(0), 3);
902+
/// assert_eq!(d.remove(0), 1);
903+
/// ```
904+
#[unstable(feature = "linked_list_remove", issue = "69210")]
905+
pub fn remove(&mut self, at: usize) -> T {
906+
let len = self.len();
907+
assert!(at < len, "Cannot remove at an index outside of the list bounds");
908+
909+
// Below, we iterate towards the node at the given index, either from
910+
// the start or the end, depending on which would be faster.
911+
let offset_from_end = len - at - 1;
912+
if at <= offset_from_end {
913+
let mut cursor = self.cursor_front_mut();
914+
for _ in 0..at {
915+
cursor.move_next();
916+
}
917+
cursor.remove_current().unwrap()
918+
} else {
919+
let mut cursor = self.cursor_back_mut();
920+
for _ in 0..offset_from_end {
921+
cursor.move_prev();
922+
}
923+
cursor.remove_current().unwrap()
924+
}
925+
}
926+
881927
/// Creates an iterator which uses a closure to determine if an element should be removed.
882928
///
883929
/// If the closure returns true, then the element is removed and yielded.

src/libcore/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,14 @@
7373
#![feature(const_ascii_ctype_on_intrinsics)]
7474
#![feature(const_alloc_layout)]
7575
#![feature(const_if_match)]
76+
#![feature(const_loop)]
7677
#![feature(const_checked_int_methods)]
7778
#![feature(const_euclidean_int_methods)]
7879
#![feature(const_overflowing_int_methods)]
7980
#![feature(const_saturating_int_methods)]
8081
#![feature(const_int_unchecked_arith)]
82+
#![feature(const_int_pow)]
83+
#![feature(constctlz)]
8184
#![feature(const_panic)]
8285
#![feature(const_fn_union)]
8386
#![feature(const_generics)]

src/libcore/num/mod.rs

+46-23
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,18 @@ use crate::convert::Infallible;
88
use crate::fmt;
99
use crate::intrinsics;
1010
use crate::mem;
11-
use crate::ops;
1211
use crate::str::FromStr;
1312

13+
// Used because the `?` operator is not allowed in a const context.
14+
macro_rules! try_opt {
15+
($e:expr) => {
16+
match $e {
17+
Some(x) => x,
18+
None => return None,
19+
}
20+
};
21+
}
22+
1423
macro_rules! impl_nonzero_fmt {
1524
( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
1625
$(
@@ -993,26 +1002,27 @@ $EndFeature, "
9931002
```"),
9941003

9951004
#[stable(feature = "no_panic_pow", since = "1.34.0")]
1005+
#[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
9961006
#[must_use = "this returns the result of the operation, \
9971007
without modifying the original"]
9981008
#[inline]
999-
pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
1009+
pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
10001010
let mut base = self;
10011011
let mut acc: Self = 1;
10021012

10031013
while exp > 1 {
10041014
if (exp & 1) == 1 {
1005-
acc = acc.checked_mul(base)?;
1015+
acc = try_opt!(acc.checked_mul(base));
10061016
}
10071017
exp /= 2;
1008-
base = base.checked_mul(base)?;
1018+
base = try_opt!(base.checked_mul(base));
10091019
}
10101020

10111021
// Deal with the final bit of the exponent separately, since
10121022
// squaring the base afterwards is not necessary and may cause a
10131023
// needless overflow.
10141024
if exp == 1 {
1015-
acc = acc.checked_mul(base)?;
1025+
acc = try_opt!(acc.checked_mul(base));
10161026
}
10171027

10181028
Some(acc)
@@ -1180,10 +1190,11 @@ assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(3), ", stringify!($SelfT
11801190
$EndFeature, "
11811191
```"),
11821192
#[stable(feature = "no_panic_pow", since = "1.34.0")]
1193+
#[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
11831194
#[must_use = "this returns the result of the operation, \
11841195
without modifying the original"]
11851196
#[inline]
1186-
pub fn saturating_pow(self, exp: u32) -> Self {
1197+
pub const fn saturating_pow(self, exp: u32) -> Self {
11871198
match self.checked_pow(exp) {
11881199
Some(x) => x,
11891200
None if self < 0 && exp % 2 == 1 => Self::min_value(),
@@ -1523,10 +1534,11 @@ assert_eq!(3i8.wrapping_pow(6), -39);",
15231534
$EndFeature, "
15241535
```"),
15251536
#[stable(feature = "no_panic_pow", since = "1.34.0")]
1537+
#[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
15261538
#[must_use = "this returns the result of the operation, \
15271539
without modifying the original"]
15281540
#[inline]
1529-
pub fn wrapping_pow(self, mut exp: u32) -> Self {
1541+
pub const fn wrapping_pow(self, mut exp: u32) -> Self {
15301542
let mut base = self;
15311543
let mut acc: Self = 1;
15321544

@@ -1900,10 +1912,11 @@ assert_eq!(3i8.overflowing_pow(5), (-13, true));",
19001912
$EndFeature, "
19011913
```"),
19021914
#[stable(feature = "no_panic_pow", since = "1.34.0")]
1915+
#[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
19031916
#[must_use = "this returns the result of the operation, \
19041917
without modifying the original"]
19051918
#[inline]
1906-
pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
1919+
pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
19071920
let mut base = self;
19081921
let mut acc: Self = 1;
19091922
let mut overflown = false;
@@ -1949,11 +1962,12 @@ assert_eq!(x.pow(5), 32);",
19491962
$EndFeature, "
19501963
```"),
19511964
#[stable(feature = "rust1", since = "1.0.0")]
1965+
#[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
19521966
#[must_use = "this returns the result of the operation, \
19531967
without modifying the original"]
19541968
#[inline]
19551969
#[rustc_inherit_overflow_checks]
1956-
pub fn pow(self, mut exp: u32) -> Self {
1970+
pub const fn pow(self, mut exp: u32) -> Self {
19571971
let mut base = self;
19581972
let mut acc = 1;
19591973

@@ -3119,26 +3133,27 @@ Basic usage:
31193133
assert_eq!(", stringify!($SelfT), "::max_value().checked_pow(2), None);", $EndFeature, "
31203134
```"),
31213135
#[stable(feature = "no_panic_pow", since = "1.34.0")]
3136+
#[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
31223137
#[must_use = "this returns the result of the operation, \
31233138
without modifying the original"]
31243139
#[inline]
3125-
pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
3140+
pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
31263141
let mut base = self;
31273142
let mut acc: Self = 1;
31283143

31293144
while exp > 1 {
31303145
if (exp & 1) == 1 {
3131-
acc = acc.checked_mul(base)?;
3146+
acc = try_opt!(acc.checked_mul(base));
31323147
}
31333148
exp /= 2;
3134-
base = base.checked_mul(base)?;
3149+
base = try_opt!(base.checked_mul(base));
31353150
}
31363151

31373152
// Deal with the final bit of the exponent separately, since
31383153
// squaring the base afterwards is not necessary and may cause a
31393154
// needless overflow.
31403155
if exp == 1 {
3141-
acc = acc.checked_mul(base)?;
3156+
acc = try_opt!(acc.checked_mul(base));
31423157
}
31433158

31443159
Some(acc)
@@ -3234,10 +3249,11 @@ assert_eq!(", stringify!($SelfT), "::MAX.saturating_pow(2), ", stringify!($SelfT
32343249
$EndFeature, "
32353250
```"),
32363251
#[stable(feature = "no_panic_pow", since = "1.34.0")]
3252+
#[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
32373253
#[must_use = "this returns the result of the operation, \
32383254
without modifying the original"]
32393255
#[inline]
3240-
pub fn saturating_pow(self, exp: u32) -> Self {
3256+
pub const fn saturating_pow(self, exp: u32) -> Self {
32413257
match self.checked_pow(exp) {
32423258
Some(x) => x,
32433259
None => Self::max_value(),
@@ -3527,10 +3543,11 @@ Basic usage:
35273543
assert_eq!(3u8.wrapping_pow(6), 217);", $EndFeature, "
35283544
```"),
35293545
#[stable(feature = "no_panic_pow", since = "1.34.0")]
3546+
#[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
35303547
#[must_use = "this returns the result of the operation, \
35313548
without modifying the original"]
35323549
#[inline]
3533-
pub fn wrapping_pow(self, mut exp: u32) -> Self {
3550+
pub const fn wrapping_pow(self, mut exp: u32) -> Self {
35343551
let mut base = self;
35353552
let mut acc: Self = 1;
35363553

@@ -3853,10 +3870,11 @@ Basic usage:
38533870
assert_eq!(3u8.overflowing_pow(6), (217, true));", $EndFeature, "
38543871
```"),
38553872
#[stable(feature = "no_panic_pow", since = "1.34.0")]
3873+
#[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
38563874
#[must_use = "this returns the result of the operation, \
38573875
without modifying the original"]
38583876
#[inline]
3859-
pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
3877+
pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
38603878
let mut base = self;
38613879
let mut acc: Self = 1;
38623880
let mut overflown = false;
@@ -3899,11 +3917,12 @@ Basic usage:
38993917
", $Feature, "assert_eq!(2", stringify!($SelfT), ".pow(5), 32);", $EndFeature, "
39003918
```"),
39013919
#[stable(feature = "rust1", since = "1.0.0")]
3920+
#[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
39023921
#[must_use = "this returns the result of the operation, \
39033922
without modifying the original"]
39043923
#[inline]
39053924
#[rustc_inherit_overflow_checks]
3906-
pub fn pow(self, mut exp: u32) -> Self {
3925+
pub const fn pow(self, mut exp: u32) -> Self {
39073926
let mut base = self;
39083927
let mut acc = 1;
39093928

@@ -4014,7 +4033,8 @@ assert!(!10", stringify!($SelfT), ".is_power_of_two());", $EndFeature, "
40144033
// overflow cases it instead ends up returning the maximum value
40154034
// of the type, and can return 0 for 0.
40164035
#[inline]
4017-
fn one_less_than_next_power_of_two(self) -> Self {
4036+
#[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
4037+
const fn one_less_than_next_power_of_two(self) -> Self {
40184038
if self <= 1 { return 0; }
40194039

40204040
let p = self - 1;
@@ -4042,10 +4062,11 @@ Basic usage:
40424062
assert_eq!(3", stringify!($SelfT), ".next_power_of_two(), 4);", $EndFeature, "
40434063
```"),
40444064
#[stable(feature = "rust1", since = "1.0.0")]
4065+
#[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
40454066
#[inline]
4046-
pub fn next_power_of_two(self) -> Self {
4047-
// Call the trait to get overflow checks
4048-
ops::Add::add(self.one_less_than_next_power_of_two(), 1)
4067+
#[rustc_inherit_overflow_checks]
4068+
pub const fn next_power_of_two(self) -> Self {
4069+
self.one_less_than_next_power_of_two() + 1
40494070
}
40504071
}
40514072

@@ -4067,7 +4088,8 @@ $EndFeature, "
40674088
```"),
40684089
#[inline]
40694090
#[stable(feature = "rust1", since = "1.0.0")]
4070-
pub fn checked_next_power_of_two(self) -> Option<Self> {
4091+
#[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
4092+
pub const fn checked_next_power_of_two(self) -> Option<Self> {
40714093
self.one_less_than_next_power_of_two().checked_add(1)
40724094
}
40734095
}
@@ -4091,7 +4113,8 @@ $EndFeature, "
40914113
```"),
40924114
#[unstable(feature = "wrapping_next_power_of_two", issue = "32463",
40934115
reason = "needs decision on wrapping behaviour")]
4094-
pub fn wrapping_next_power_of_two(self) -> Self {
4116+
#[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
4117+
pub const fn wrapping_next_power_of_two(self) -> Self {
40954118
self.one_less_than_next_power_of_two().wrapping_add(1)
40964119
}
40974120
}
+23-7
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
1-
This error occurs when an `if` expression without an `else` block is used in a
2-
context where a type other than `()` is expected, for example a `let`
3-
expression:
1+
An `if` expression is missing an `else` block.
2+
3+
Erroneous code example:
44

55
```compile_fail,E0317
6-
fn main() {
7-
let x = 5;
8-
let a = if x == 5 { 1 };
9-
}
6+
let x = 5;
7+
let a = if x == 5 {
8+
1
9+
};
1010
```
1111

12+
This error occurs when an `if` expression without an `else` block is used in a
13+
context where a type other than `()` is expected. In the previous code example,
14+
the `let` expression was expecting a value but since there was no `else`, no
15+
value was returned.
16+
1217
An `if` expression without an `else` block has the type `()`, so this is a type
1318
error. To resolve it, add an `else` block having the same type as the `if`
1419
block.
20+
21+
So to fix the previous code example:
22+
23+
```
24+
let x = 5;
25+
let a = if x == 5 {
26+
1
27+
} else {
28+
2
29+
};
30+
```

src/librustc_span/lib.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -1075,7 +1075,7 @@ impl SourceFile {
10751075
unmapped_path: FileName,
10761076
mut src: String,
10771077
start_pos: BytePos,
1078-
) -> Result<SourceFile, OffsetOverflowError> {
1078+
) -> Self {
10791079
let normalized_pos = normalize_src(&mut src, start_pos);
10801080

10811081
let src_hash = {
@@ -1089,14 +1089,12 @@ impl SourceFile {
10891089
hasher.finish::<u128>()
10901090
};
10911091
let end_pos = start_pos.to_usize() + src.len();
1092-
if end_pos > u32::max_value() as usize {
1093-
return Err(OffsetOverflowError);
1094-
}
1092+
assert!(end_pos <= u32::max_value() as usize);
10951093

10961094
let (lines, multibyte_chars, non_narrow_chars) =
10971095
analyze_source_file::analyze_source_file(&src[..], start_pos);
10981096

1099-
Ok(SourceFile {
1097+
SourceFile {
11001098
name,
11011099
name_was_remapped,
11021100
unmapped_path: Some(unmapped_path),
@@ -1111,7 +1109,7 @@ impl SourceFile {
11111109
non_narrow_chars,
11121110
normalized_pos,
11131111
name_hash,
1114-
})
1112+
}
11151113
}
11161114

11171115
/// Returns the `BytePos` of the beginning of the current line.

0 commit comments

Comments
 (0)