Skip to content

Commit

Permalink
Auto merge of rust-lang#134605 - jhpratt:rollup-quiss71, r=jhpratt
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Dec 21, 2024
2 parents 73c278f + ea8bc3b commit 6076bee
Show file tree
Hide file tree
Showing 24 changed files with 379 additions and 110 deletions.
7 changes: 4 additions & 3 deletions compiler/rustc_ast/src/util/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,10 @@ impl AssocOp {
match *self {
Assign | AssignOp(_) => Fixity::Right,
As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd
| BitXor | BitOr | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual
| LAnd | LOr => Fixity::Left,
DotDot | DotDotEq => Fixity::None,
| BitXor | BitOr | LAnd | LOr => Fixity::Left,
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | DotDot | DotDotEq => {
Fixity::None
}
}
}

Expand Down
20 changes: 10 additions & 10 deletions compiler/rustc_mir_build/src/builder/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1481,14 +1481,6 @@ fn build_scope_drops<'tcx>(
block = next;
}
DropKind::ForLint => {
// If the operand has been moved, and we are not on an unwind
// path, then don't generate the drop. (We only take this into
// account for non-unwind paths so as not to disturb the
// caching mechanism.)
if scope.moved_locals.iter().any(|&o| o == local) {
continue;
}

// As in the `DropKind::Storage` case below:
// normally lint-related drops are not emitted for unwind,
// so we can just leave `unwind_to` unmodified, but in some
Expand All @@ -1500,6 +1492,14 @@ fn build_scope_drops<'tcx>(
unwind_to = unwind_drops.drops[unwind_to].next;
}

// If the operand has been moved, and we are not on an unwind
// path, then don't generate the drop. (We only take this into
// account for non-unwind paths so as not to disturb the
// caching mechanism.)
if scope.moved_locals.iter().any(|&o| o == local) {
continue;
}

cfg.push(block, Statement {
source_info,
kind: StatementKind::BackwardIncompatibleDropHint {
Expand Down Expand Up @@ -1552,7 +1552,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
let mut unwind_indices = IndexVec::from_elem_n(unwind_target, 1);
for (drop_idx, drop_node) in drops.drops.iter_enumerated().skip(1) {
match drop_node.data.kind {
DropKind::Storage => {
DropKind::Storage | DropKind::ForLint => {
if is_coroutine {
let unwind_drop = self
.scopes
Expand All @@ -1563,7 +1563,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
unwind_indices.push(unwind_indices[drop_node.next]);
}
}
DropKind::Value | DropKind::ForLint => {
DropKind::Value => {
let unwind_drop = self
.scopes
.unwind_drops
Expand Down
12 changes: 2 additions & 10 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,13 +279,9 @@ impl<'a> Parser<'a> {
break;
}

let fixity = op.fixity();
let min_prec = match fixity {
let min_prec = match op.fixity() {
Fixity::Right => Bound::Included(prec),
Fixity::Left => Bound::Excluded(prec),
// We currently have no non-associative operators that are not handled above by
// the special cases. The code is here only for future convenience.
Fixity::None => Bound::Excluded(prec),
Fixity::Left | Fixity::None => Bound::Excluded(prec),
};
let (rhs, _) = self.with_res(restrictions - Restrictions::STMT_EXPR, |this| {
let attrs = this.parse_outer_attributes()?;
Expand Down Expand Up @@ -337,10 +333,6 @@ impl<'a> Parser<'a> {
self.dcx().span_bug(span, "AssocOp should have been handled by special case")
}
};

if let Fixity::None = fixity {
break;
}
}

Ok((lhs, parsed_something))
Expand Down
55 changes: 53 additions & 2 deletions compiler/rustc_parse/src/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,51 @@ impl<'a> Parser<'a> {
Ok(self.mk_block(stmts, s, lo.to(self.prev_token.span)))
}

fn recover_missing_dot(&mut self, err: &mut Diag<'_>) {
let Some((ident, _)) = self.token.ident() else {
return;
};
if let Some(c) = ident.name.as_str().chars().next()
&& c.is_uppercase()
{
return;
}
if self.token.is_reserved_ident() && !self.token.is_ident_named(kw::Await) {
return;
}
if self.prev_token.is_reserved_ident() && self.prev_token.is_ident_named(kw::Await) {
// Likely `foo.await bar`
} else if !self.prev_token.is_reserved_ident() && self.prev_token.is_ident() {
// Likely `foo bar`
} else if self.prev_token.kind == token::Question {
// `foo? bar`
} else if self.prev_token.kind == token::CloseDelim(Delimiter::Parenthesis) {
// `foo() bar`
} else {
return;
}
if self.token.span == self.prev_token.span {
// Account for syntax errors in proc-macros.
return;
}
if self.look_ahead(1, |t| [token::Semi, token::Question, token::Dot].contains(&t.kind)) {
err.span_suggestion_verbose(
self.prev_token.span.between(self.token.span),
"you might have meant to write a field access",
".".to_string(),
Applicability::MaybeIncorrect,
);
}
if self.look_ahead(1, |t| t.kind == token::OpenDelim(Delimiter::Parenthesis)) {
err.span_suggestion_verbose(
self.prev_token.span.between(self.token.span),
"you might have meant to write a method call",
".".to_string(),
Applicability::MaybeIncorrect,
);
}
}

/// Parses a statement, including the trailing semicolon.
pub fn parse_full_stmt(
&mut self,
Expand Down Expand Up @@ -851,7 +896,8 @@ impl<'a> Parser<'a> {
Some(if recover.no() {
res?
} else {
res.unwrap_or_else(|e| {
res.unwrap_or_else(|mut e| {
self.recover_missing_dot(&mut e);
let guar = e.emit();
self.recover_stmt();
guar
Expand All @@ -872,7 +918,12 @@ impl<'a> Parser<'a> {
// We might be at the `,` in `let x = foo<bar, baz>;`. Try to recover.
match &mut local.kind {
LocalKind::Init(expr) | LocalKind::InitElse(expr, _) => {
self.check_mistyped_turbofish_with_multiple_type_params(e, expr)?;
self.check_mistyped_turbofish_with_multiple_type_params(e, expr).map_err(
|mut e| {
self.recover_missing_dot(&mut e);
e
},
)?;
// We found `foo<bar, baz>`, have we fully recovered?
self.expect_semi()?;
}
Expand Down
3 changes: 1 addition & 2 deletions library/alloc/src/collections/binary_heap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,8 +531,7 @@ impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
/// heap.push(1);
/// heap.push(5);
/// heap.push(2);
/// {
/// let mut val = heap.peek_mut().unwrap();
/// if let Some(mut val) = heap.peek_mut() {
/// *val = 0;
/// }
/// assert_eq!(heap.peek(), Some(&2));
Expand Down
12 changes: 7 additions & 5 deletions library/core/src/cell/once.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,9 @@ impl<T> OnceCell<T> {
///
/// let value = cell.get_mut_or_try_init(|| "1234".parse());
/// assert_eq!(value, Ok(&mut 1234));
/// *value.unwrap() += 2;
///
/// let Ok(value) = value else { return; };
/// *value += 2;
/// assert_eq!(cell.get(), Some(&1236))
/// ```
#[unstable(feature = "once_cell_get_mut", issue = "121641")]
Expand Down Expand Up @@ -304,8 +306,8 @@ impl<T> OnceCell<T> {
/// assert_eq!(cell.into_inner(), None);
///
/// let cell = OnceCell::new();
/// cell.set("hello".to_string()).unwrap();
/// assert_eq!(cell.into_inner(), Some("hello".to_string()));
/// let _ = cell.set("hello".to_owned());
/// assert_eq!(cell.into_inner(), Some("hello".to_owned()));
/// ```
#[inline]
#[stable(feature = "once_cell", since = "1.70.0")]
Expand All @@ -332,8 +334,8 @@ impl<T> OnceCell<T> {
/// assert_eq!(cell.take(), None);
///
/// let mut cell = OnceCell::new();
/// cell.set("hello".to_string()).unwrap();
/// assert_eq!(cell.take(), Some("hello".to_string()));
/// let _ = cell.set("hello".to_owned());
/// assert_eq!(cell.take(), Some("hello".to_owned()));
/// assert_eq!(cell.get(), None);
/// ```
#[inline]
Expand Down
11 changes: 7 additions & 4 deletions library/core/src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,9 @@ pub trait Write {
/// }
///
/// let mut buf = String::new();
/// writer(&mut buf, "hola").unwrap();
/// writer(&mut buf, "hola")?;
/// assert_eq!(&buf, "hola");
/// # std::fmt::Result::Ok(())
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn write_str(&mut self, s: &str) -> Result;
Expand All @@ -179,9 +180,10 @@ pub trait Write {
/// }
///
/// let mut buf = String::new();
/// writer(&mut buf, 'a').unwrap();
/// writer(&mut buf, 'b').unwrap();
/// writer(&mut buf, 'a')?;
/// writer(&mut buf, 'b')?;
/// assert_eq!(&buf, "ab");
/// # std::fmt::Result::Ok(())
/// ```
#[stable(feature = "fmt_write_char", since = "1.1.0")]
fn write_char(&mut self, c: char) -> Result {
Expand All @@ -208,8 +210,9 @@ pub trait Write {
/// }
///
/// let mut buf = String::new();
/// writer(&mut buf, "world").unwrap();
/// writer(&mut buf, "world")?;
/// assert_eq!(&buf, "world");
/// # std::fmt::Result::Ok(())
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn write_fmt(&mut self, args: Arguments<'_>) -> Result {
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/iter/sources/once.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use crate::iter::{FusedIterator, TrustedLen};
/// use std::fs;
/// use std::path::PathBuf;
///
/// let dirs = fs::read_dir(".foo").unwrap();
/// let dirs = fs::read_dir(".foo")?;
///
/// // we need to convert from an iterator of DirEntry-s to an iterator of
/// // PathBufs, so we use map
Expand All @@ -50,6 +50,7 @@ use crate::iter::{FusedIterator, TrustedLen};
/// for f in files {
/// println!("{f:?}");
/// }
/// # std::io::Result::Ok(())
/// ```
#[stable(feature = "iter_once", since = "1.2.0")]
pub fn once<T>(value: T) -> Once<T> {
Expand Down
6 changes: 3 additions & 3 deletions library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2564,7 +2564,7 @@ pub trait Iterator {
/// # Example
///
/// ```
/// let reduced: i32 = (1..10).reduce(|acc, e| acc + e).unwrap();
/// let reduced: i32 = (1..10).reduce(|acc, e| acc + e).unwrap_or(0);
/// assert_eq!(reduced, 45);
///
/// // Which is equivalent to doing it with `fold`:
Expand Down Expand Up @@ -3087,7 +3087,7 @@ pub trait Iterator {
/// [2.4, f32::NAN, 1.3]
/// .into_iter()
/// .reduce(f32::max)
/// .unwrap(),
/// .unwrap_or(0.),
/// 2.4
/// );
/// ```
Expand Down Expand Up @@ -3123,7 +3123,7 @@ pub trait Iterator {
/// [2.4, f32::NAN, 1.3]
/// .into_iter()
/// .reduce(f32::min)
/// .unwrap(),
/// .unwrap_or(0.),
/// 1.3
/// );
/// ```
Expand Down
8 changes: 7 additions & 1 deletion library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -937,10 +937,16 @@ impl<T> Option<T> {
/// Returns the contained [`Some`] value, consuming the `self` value.
///
/// Because this function may panic, its use is generally discouraged.
/// Panics are meant for unrecoverable errors, and
/// [may abort the entire program][panic-abort].
///
/// Instead, prefer to use pattern matching and handle the [`None`]
/// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or
/// [`unwrap_or_default`].
/// [`unwrap_or_default`]. In functions returning `Option`, you can use
/// [the `?` (try) operator][try-option].
///
/// [panic-abort]: https://doc.rust-lang.org/book/ch09-01-unrecoverable-errors-with-panic.html
/// [try-option]: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#where-the--operator-can-be-used
/// [`unwrap_or`]: Option::unwrap_or
/// [`unwrap_or_else`]: Option::unwrap_or_else
/// [`unwrap_or_default`]: Option::unwrap_or_default
Expand Down
9 changes: 6 additions & 3 deletions library/core/src/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,11 +502,12 @@ impl<T: ?Sized> *const T {
/// let mut out = String::new();
/// while ptr != end_rounded_up {
/// unsafe {
/// write!(&mut out, "{}, ", *ptr).unwrap();
/// write!(&mut out, "{}, ", *ptr)?;
/// }
/// ptr = ptr.wrapping_offset(step);
/// }
/// assert_eq!(out.as_str(), "1, 3, 5, ");
/// # std::fmt::Result::Ok(())
/// ```
#[stable(feature = "ptr_wrapping_offset", since = "1.16.0")]
#[must_use = "returns a new pointer rather than modifying its argument"]
Expand Down Expand Up @@ -1125,11 +1126,12 @@ impl<T: ?Sized> *const T {
/// let mut out = String::new();
/// while ptr != end_rounded_up {
/// unsafe {
/// write!(&mut out, "{}, ", *ptr).unwrap();
/// write!(&mut out, "{}, ", *ptr)?;
/// }
/// ptr = ptr.wrapping_add(step);
/// }
/// assert_eq!(out, "1, 3, 5, ");
/// # std::fmt::Result::Ok(())
/// ```
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[must_use = "returns a new pointer rather than modifying its argument"]
Expand Down Expand Up @@ -1203,11 +1205,12 @@ impl<T: ?Sized> *const T {
/// let mut out = String::new();
/// while ptr != start_rounded_down {
/// unsafe {
/// write!(&mut out, "{}, ", *ptr).unwrap();
/// write!(&mut out, "{}, ", *ptr)?;
/// }
/// ptr = ptr.wrapping_sub(step);
/// }
/// assert_eq!(out, "5, 3, 1, ");
/// # std::fmt::Result::Ok(())
/// ```
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[must_use = "returns a new pointer rather than modifying its argument"]
Expand Down
11 changes: 8 additions & 3 deletions library/core/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1065,10 +1065,15 @@ impl<T, E> Result<T, E> {
/// Returns the contained [`Ok`] value, consuming the `self` value.
///
/// Because this function may panic, its use is generally discouraged.
/// Instead, prefer to use pattern matching and handle the [`Err`]
/// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or
/// [`unwrap_or_default`].
/// Panics are meant for unrecoverable errors, and
/// [may abort the entire program][panic-abort].
///
/// Instead, prefer to use [the `?` (try) operator][try-operator], or pattern matching
/// to handle the [`Err`] case explicitly, or call [`unwrap_or`],
/// [`unwrap_or_else`], or [`unwrap_or_default`].
///
/// [panic-abort]: https://doc.rust-lang.org/book/ch09-01-unrecoverable-errors-with-panic.html
/// [try-operator]: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator
/// [`unwrap_or`]: Result::unwrap_or
/// [`unwrap_or_else`]: Result::unwrap_or_else
/// [`unwrap_or_default`]: Result::unwrap_or_default
Expand Down
Loading

0 comments on commit 6076bee

Please sign in to comment.