Skip to content

Commit 6076bee

Browse files
committed
Auto merge of rust-lang#134605 - jhpratt:rollup-quiss71, r=jhpratt
Rollup of 7 pull requests Successful merges: - rust-lang#133087 (Detect missing `.` in method chain in `let` bindings and statements) - rust-lang#134575 (Handle `DropKind::ForLint` in coroutines correctly) - rust-lang#134576 (Improve prose around basic examples of Iter and IterMut) - rust-lang#134577 (Improve prose around `as_slice` example of Iter) - rust-lang#134579 (Improve prose around into_slice example of IterMut) - rust-lang#134593 (Less unwrap() in documentation) - rust-lang#134600 (Fix parenthesization of chained comparisons by pretty-printer) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 73c278f + ea8bc3b commit 6076bee

24 files changed

+379
-110
lines changed

compiler/rustc_ast/src/util/parser.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,10 @@ impl AssocOp {
153153
match *self {
154154
Assign | AssignOp(_) => Fixity::Right,
155155
As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd
156-
| BitXor | BitOr | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual
157-
| LAnd | LOr => Fixity::Left,
158-
DotDot | DotDotEq => Fixity::None,
156+
| BitXor | BitOr | LAnd | LOr => Fixity::Left,
157+
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | DotDot | DotDotEq => {
158+
Fixity::None
159+
}
159160
}
160161
}
161162

compiler/rustc_mir_build/src/builder/scope.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -1481,14 +1481,6 @@ fn build_scope_drops<'tcx>(
14811481
block = next;
14821482
}
14831483
DropKind::ForLint => {
1484-
// If the operand has been moved, and we are not on an unwind
1485-
// path, then don't generate the drop. (We only take this into
1486-
// account for non-unwind paths so as not to disturb the
1487-
// caching mechanism.)
1488-
if scope.moved_locals.iter().any(|&o| o == local) {
1489-
continue;
1490-
}
1491-
14921484
// As in the `DropKind::Storage` case below:
14931485
// normally lint-related drops are not emitted for unwind,
14941486
// so we can just leave `unwind_to` unmodified, but in some
@@ -1500,6 +1492,14 @@ fn build_scope_drops<'tcx>(
15001492
unwind_to = unwind_drops.drops[unwind_to].next;
15011493
}
15021494

1495+
// If the operand has been moved, and we are not on an unwind
1496+
// path, then don't generate the drop. (We only take this into
1497+
// account for non-unwind paths so as not to disturb the
1498+
// caching mechanism.)
1499+
if scope.moved_locals.iter().any(|&o| o == local) {
1500+
continue;
1501+
}
1502+
15031503
cfg.push(block, Statement {
15041504
source_info,
15051505
kind: StatementKind::BackwardIncompatibleDropHint {
@@ -1552,7 +1552,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
15521552
let mut unwind_indices = IndexVec::from_elem_n(unwind_target, 1);
15531553
for (drop_idx, drop_node) in drops.drops.iter_enumerated().skip(1) {
15541554
match drop_node.data.kind {
1555-
DropKind::Storage => {
1555+
DropKind::Storage | DropKind::ForLint => {
15561556
if is_coroutine {
15571557
let unwind_drop = self
15581558
.scopes
@@ -1563,7 +1563,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
15631563
unwind_indices.push(unwind_indices[drop_node.next]);
15641564
}
15651565
}
1566-
DropKind::Value | DropKind::ForLint => {
1566+
DropKind::Value => {
15671567
let unwind_drop = self
15681568
.scopes
15691569
.unwind_drops

compiler/rustc_parse/src/parser/expr.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -279,13 +279,9 @@ impl<'a> Parser<'a> {
279279
break;
280280
}
281281

282-
let fixity = op.fixity();
283-
let min_prec = match fixity {
282+
let min_prec = match op.fixity() {
284283
Fixity::Right => Bound::Included(prec),
285-
Fixity::Left => Bound::Excluded(prec),
286-
// We currently have no non-associative operators that are not handled above by
287-
// the special cases. The code is here only for future convenience.
288-
Fixity::None => Bound::Excluded(prec),
284+
Fixity::Left | Fixity::None => Bound::Excluded(prec),
289285
};
290286
let (rhs, _) = self.with_res(restrictions - Restrictions::STMT_EXPR, |this| {
291287
let attrs = this.parse_outer_attributes()?;
@@ -337,10 +333,6 @@ impl<'a> Parser<'a> {
337333
self.dcx().span_bug(span, "AssocOp should have been handled by special case")
338334
}
339335
};
340-
341-
if let Fixity::None = fixity {
342-
break;
343-
}
344336
}
345337

346338
Ok((lhs, parsed_something))

compiler/rustc_parse/src/parser/stmt.rs

+53-2
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,51 @@ impl<'a> Parser<'a> {
745745
Ok(self.mk_block(stmts, s, lo.to(self.prev_token.span)))
746746
}
747747

748+
fn recover_missing_dot(&mut self, err: &mut Diag<'_>) {
749+
let Some((ident, _)) = self.token.ident() else {
750+
return;
751+
};
752+
if let Some(c) = ident.name.as_str().chars().next()
753+
&& c.is_uppercase()
754+
{
755+
return;
756+
}
757+
if self.token.is_reserved_ident() && !self.token.is_ident_named(kw::Await) {
758+
return;
759+
}
760+
if self.prev_token.is_reserved_ident() && self.prev_token.is_ident_named(kw::Await) {
761+
// Likely `foo.await bar`
762+
} else if !self.prev_token.is_reserved_ident() && self.prev_token.is_ident() {
763+
// Likely `foo bar`
764+
} else if self.prev_token.kind == token::Question {
765+
// `foo? bar`
766+
} else if self.prev_token.kind == token::CloseDelim(Delimiter::Parenthesis) {
767+
// `foo() bar`
768+
} else {
769+
return;
770+
}
771+
if self.token.span == self.prev_token.span {
772+
// Account for syntax errors in proc-macros.
773+
return;
774+
}
775+
if self.look_ahead(1, |t| [token::Semi, token::Question, token::Dot].contains(&t.kind)) {
776+
err.span_suggestion_verbose(
777+
self.prev_token.span.between(self.token.span),
778+
"you might have meant to write a field access",
779+
".".to_string(),
780+
Applicability::MaybeIncorrect,
781+
);
782+
}
783+
if self.look_ahead(1, |t| t.kind == token::OpenDelim(Delimiter::Parenthesis)) {
784+
err.span_suggestion_verbose(
785+
self.prev_token.span.between(self.token.span),
786+
"you might have meant to write a method call",
787+
".".to_string(),
788+
Applicability::MaybeIncorrect,
789+
);
790+
}
791+
}
792+
748793
/// Parses a statement, including the trailing semicolon.
749794
pub fn parse_full_stmt(
750795
&mut self,
@@ -851,7 +896,8 @@ impl<'a> Parser<'a> {
851896
Some(if recover.no() {
852897
res?
853898
} else {
854-
res.unwrap_or_else(|e| {
899+
res.unwrap_or_else(|mut e| {
900+
self.recover_missing_dot(&mut e);
855901
let guar = e.emit();
856902
self.recover_stmt();
857903
guar
@@ -872,7 +918,12 @@ impl<'a> Parser<'a> {
872918
// We might be at the `,` in `let x = foo<bar, baz>;`. Try to recover.
873919
match &mut local.kind {
874920
LocalKind::Init(expr) | LocalKind::InitElse(expr, _) => {
875-
self.check_mistyped_turbofish_with_multiple_type_params(e, expr)?;
921+
self.check_mistyped_turbofish_with_multiple_type_params(e, expr).map_err(
922+
|mut e| {
923+
self.recover_missing_dot(&mut e);
924+
e
925+
},
926+
)?;
876927
// We found `foo<bar, baz>`, have we fully recovered?
877928
self.expect_semi()?;
878929
}

library/alloc/src/collections/binary_heap/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -531,8 +531,7 @@ impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
531531
/// heap.push(1);
532532
/// heap.push(5);
533533
/// heap.push(2);
534-
/// {
535-
/// let mut val = heap.peek_mut().unwrap();
534+
/// if let Some(mut val) = heap.peek_mut() {
536535
/// *val = 0;
537536
/// }
538537
/// assert_eq!(heap.peek(), Some(&2));

library/core/src/cell/once.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,9 @@ impl<T> OnceCell<T> {
262262
///
263263
/// let value = cell.get_mut_or_try_init(|| "1234".parse());
264264
/// assert_eq!(value, Ok(&mut 1234));
265-
/// *value.unwrap() += 2;
265+
///
266+
/// let Ok(value) = value else { return; };
267+
/// *value += 2;
266268
/// assert_eq!(cell.get(), Some(&1236))
267269
/// ```
268270
#[unstable(feature = "once_cell_get_mut", issue = "121641")]
@@ -304,8 +306,8 @@ impl<T> OnceCell<T> {
304306
/// assert_eq!(cell.into_inner(), None);
305307
///
306308
/// let cell = OnceCell::new();
307-
/// cell.set("hello".to_string()).unwrap();
308-
/// assert_eq!(cell.into_inner(), Some("hello".to_string()));
309+
/// let _ = cell.set("hello".to_owned());
310+
/// assert_eq!(cell.into_inner(), Some("hello".to_owned()));
309311
/// ```
310312
#[inline]
311313
#[stable(feature = "once_cell", since = "1.70.0")]
@@ -332,8 +334,8 @@ impl<T> OnceCell<T> {
332334
/// assert_eq!(cell.take(), None);
333335
///
334336
/// let mut cell = OnceCell::new();
335-
/// cell.set("hello".to_string()).unwrap();
336-
/// assert_eq!(cell.take(), Some("hello".to_string()));
337+
/// let _ = cell.set("hello".to_owned());
338+
/// assert_eq!(cell.take(), Some("hello".to_owned()));
337339
/// assert_eq!(cell.get(), None);
338340
/// ```
339341
#[inline]

library/core/src/fmt/mod.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,9 @@ pub trait Write {
152152
/// }
153153
///
154154
/// let mut buf = String::new();
155-
/// writer(&mut buf, "hola").unwrap();
155+
/// writer(&mut buf, "hola")?;
156156
/// assert_eq!(&buf, "hola");
157+
/// # std::fmt::Result::Ok(())
157158
/// ```
158159
#[stable(feature = "rust1", since = "1.0.0")]
159160
fn write_str(&mut self, s: &str) -> Result;
@@ -179,9 +180,10 @@ pub trait Write {
179180
/// }
180181
///
181182
/// let mut buf = String::new();
182-
/// writer(&mut buf, 'a').unwrap();
183-
/// writer(&mut buf, 'b').unwrap();
183+
/// writer(&mut buf, 'a')?;
184+
/// writer(&mut buf, 'b')?;
184185
/// assert_eq!(&buf, "ab");
186+
/// # std::fmt::Result::Ok(())
185187
/// ```
186188
#[stable(feature = "fmt_write_char", since = "1.1.0")]
187189
fn write_char(&mut self, c: char) -> Result {
@@ -208,8 +210,9 @@ pub trait Write {
208210
/// }
209211
///
210212
/// let mut buf = String::new();
211-
/// writer(&mut buf, "world").unwrap();
213+
/// writer(&mut buf, "world")?;
212214
/// assert_eq!(&buf, "world");
215+
/// # std::fmt::Result::Ok(())
213216
/// ```
214217
#[stable(feature = "rust1", since = "1.0.0")]
215218
fn write_fmt(&mut self, args: Arguments<'_>) -> Result {

library/core/src/iter/sources/once.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use crate::iter::{FusedIterator, TrustedLen};
3434
/// use std::fs;
3535
/// use std::path::PathBuf;
3636
///
37-
/// let dirs = fs::read_dir(".foo").unwrap();
37+
/// let dirs = fs::read_dir(".foo")?;
3838
///
3939
/// // we need to convert from an iterator of DirEntry-s to an iterator of
4040
/// // PathBufs, so we use map
@@ -50,6 +50,7 @@ use crate::iter::{FusedIterator, TrustedLen};
5050
/// for f in files {
5151
/// println!("{f:?}");
5252
/// }
53+
/// # std::io::Result::Ok(())
5354
/// ```
5455
#[stable(feature = "iter_once", since = "1.2.0")]
5556
pub fn once<T>(value: T) -> Once<T> {

library/core/src/iter/traits/iterator.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2564,7 +2564,7 @@ pub trait Iterator {
25642564
/// # Example
25652565
///
25662566
/// ```
2567-
/// let reduced: i32 = (1..10).reduce(|acc, e| acc + e).unwrap();
2567+
/// let reduced: i32 = (1..10).reduce(|acc, e| acc + e).unwrap_or(0);
25682568
/// assert_eq!(reduced, 45);
25692569
///
25702570
/// // Which is equivalent to doing it with `fold`:
@@ -3087,7 +3087,7 @@ pub trait Iterator {
30873087
/// [2.4, f32::NAN, 1.3]
30883088
/// .into_iter()
30893089
/// .reduce(f32::max)
3090-
/// .unwrap(),
3090+
/// .unwrap_or(0.),
30913091
/// 2.4
30923092
/// );
30933093
/// ```
@@ -3123,7 +3123,7 @@ pub trait Iterator {
31233123
/// [2.4, f32::NAN, 1.3]
31243124
/// .into_iter()
31253125
/// .reduce(f32::min)
3126-
/// .unwrap(),
3126+
/// .unwrap_or(0.),
31273127
/// 1.3
31283128
/// );
31293129
/// ```

library/core/src/option.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -937,10 +937,16 @@ impl<T> Option<T> {
937937
/// Returns the contained [`Some`] value, consuming the `self` value.
938938
///
939939
/// Because this function may panic, its use is generally discouraged.
940+
/// Panics are meant for unrecoverable errors, and
941+
/// [may abort the entire program][panic-abort].
942+
///
940943
/// Instead, prefer to use pattern matching and handle the [`None`]
941944
/// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or
942-
/// [`unwrap_or_default`].
945+
/// [`unwrap_or_default`]. In functions returning `Option`, you can use
946+
/// [the `?` (try) operator][try-option].
943947
///
948+
/// [panic-abort]: https://doc.rust-lang.org/book/ch09-01-unrecoverable-errors-with-panic.html
949+
/// [try-option]: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#where-the--operator-can-be-used
944950
/// [`unwrap_or`]: Option::unwrap_or
945951
/// [`unwrap_or_else`]: Option::unwrap_or_else
946952
/// [`unwrap_or_default`]: Option::unwrap_or_default

library/core/src/ptr/const_ptr.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -502,11 +502,12 @@ impl<T: ?Sized> *const T {
502502
/// let mut out = String::new();
503503
/// while ptr != end_rounded_up {
504504
/// unsafe {
505-
/// write!(&mut out, "{}, ", *ptr).unwrap();
505+
/// write!(&mut out, "{}, ", *ptr)?;
506506
/// }
507507
/// ptr = ptr.wrapping_offset(step);
508508
/// }
509509
/// assert_eq!(out.as_str(), "1, 3, 5, ");
510+
/// # std::fmt::Result::Ok(())
510511
/// ```
511512
#[stable(feature = "ptr_wrapping_offset", since = "1.16.0")]
512513
#[must_use = "returns a new pointer rather than modifying its argument"]
@@ -1125,11 +1126,12 @@ impl<T: ?Sized> *const T {
11251126
/// let mut out = String::new();
11261127
/// while ptr != end_rounded_up {
11271128
/// unsafe {
1128-
/// write!(&mut out, "{}, ", *ptr).unwrap();
1129+
/// write!(&mut out, "{}, ", *ptr)?;
11291130
/// }
11301131
/// ptr = ptr.wrapping_add(step);
11311132
/// }
11321133
/// assert_eq!(out, "1, 3, 5, ");
1134+
/// # std::fmt::Result::Ok(())
11331135
/// ```
11341136
#[stable(feature = "pointer_methods", since = "1.26.0")]
11351137
#[must_use = "returns a new pointer rather than modifying its argument"]
@@ -1203,11 +1205,12 @@ impl<T: ?Sized> *const T {
12031205
/// let mut out = String::new();
12041206
/// while ptr != start_rounded_down {
12051207
/// unsafe {
1206-
/// write!(&mut out, "{}, ", *ptr).unwrap();
1208+
/// write!(&mut out, "{}, ", *ptr)?;
12071209
/// }
12081210
/// ptr = ptr.wrapping_sub(step);
12091211
/// }
12101212
/// assert_eq!(out, "5, 3, 1, ");
1213+
/// # std::fmt::Result::Ok(())
12111214
/// ```
12121215
#[stable(feature = "pointer_methods", since = "1.26.0")]
12131216
#[must_use = "returns a new pointer rather than modifying its argument"]

library/core/src/result.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -1065,10 +1065,15 @@ impl<T, E> Result<T, E> {
10651065
/// Returns the contained [`Ok`] value, consuming the `self` value.
10661066
///
10671067
/// Because this function may panic, its use is generally discouraged.
1068-
/// Instead, prefer to use pattern matching and handle the [`Err`]
1069-
/// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or
1070-
/// [`unwrap_or_default`].
1068+
/// Panics are meant for unrecoverable errors, and
1069+
/// [may abort the entire program][panic-abort].
1070+
///
1071+
/// Instead, prefer to use [the `?` (try) operator][try-operator], or pattern matching
1072+
/// to handle the [`Err`] case explicitly, or call [`unwrap_or`],
1073+
/// [`unwrap_or_else`], or [`unwrap_or_default`].
10711074
///
1075+
/// [panic-abort]: https://doc.rust-lang.org/book/ch09-01-unrecoverable-errors-with-panic.html
1076+
/// [try-operator]: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator
10721077
/// [`unwrap_or`]: Result::unwrap_or
10731078
/// [`unwrap_or_else`]: Result::unwrap_or_else
10741079
/// [`unwrap_or_default`]: Result::unwrap_or_default

0 commit comments

Comments
 (0)