Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #127785

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 63 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#![allow(rustc::untranslatable_diagnostic)]

use either::Either;
use hir::ClosureKind;
use hir::{ClosureKind, Path};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{codes::*, struct_span_code_err, Applicability, Diag, MultiSpan};
Expand All @@ -16,6 +16,7 @@ use rustc_hir::{CoroutineKind, CoroutineSource, LangItem};
use rustc_middle::bug;
use rustc_middle::hir::nested_filter::OnlyBodies;
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::VarDebugInfoContents;
use rustc_middle::mir::{
self, AggregateKind, BindingForm, BorrowKind, CallSource, ClearCrossCrate, ConstraintCategory,
FakeBorrowKind, FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, MutBorrowKind,
Expand Down Expand Up @@ -546,7 +547,14 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
self.suggest_cloning(err, ty, expr, None, Some(move_spans));
}
}
if let Some(pat) = finder.pat {

self.suggest_ref_for_dbg_args(expr, place, move_span, err);

// it's useless to suggest inserting `ref` when the span don't comes from local code
if let Some(pat) = finder.pat
&& !move_span.is_dummy()
&& !self.infcx.tcx.sess.source_map().is_imported(move_span)
{
*in_pattern = true;
let mut sugg = vec![(pat.span.shrink_to_lo(), "ref ".to_string())];
if let Some(pat) = finder.parent_pat {
Expand All @@ -561,6 +569,59 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
}
}

// for dbg!(x) which may take ownership, suggest dbg!(&x) instead
// but here we actually do not check whether the macro name is `dbg!`
// so that we may extend the scope a bit larger to cover more cases
fn suggest_ref_for_dbg_args(
&self,
body: &hir::Expr<'_>,
place: &Place<'tcx>,
move_span: Span,
err: &mut Diag<'infcx>,
) {
let var_info = self.body.var_debug_info.iter().find(|info| match info.value {
VarDebugInfoContents::Place(ref p) => p == place,
_ => false,
});
let arg_name = if let Some(var_info) = var_info {
var_info.name
} else {
return;
};
struct MatchArgFinder {
expr_span: Span,
match_arg_span: Option<Span>,
arg_name: Symbol,
}
impl Visitor<'_> for MatchArgFinder {
fn visit_expr(&mut self, e: &hir::Expr<'_>) {
// dbg! is expanded into a match pattern, we need to find the right argument span
if let hir::ExprKind::Match(expr, ..) = &e.kind
&& let hir::ExprKind::Path(hir::QPath::Resolved(
_,
path @ Path { segments: [seg], .. },
)) = &expr.kind
&& seg.ident.name == self.arg_name
&& self.expr_span.source_callsite().contains(expr.span)
{
self.match_arg_span = Some(path.span);
}
hir::intravisit::walk_expr(self, e);
}
}

let mut finder = MatchArgFinder { expr_span: move_span, match_arg_span: None, arg_name };
finder.visit_expr(body);
if let Some(macro_arg_span) = finder.match_arg_span {
err.span_suggestion_verbose(
macro_arg_span.shrink_to_lo(),
"consider borrowing instead of transferring ownership",
"&",
Applicability::MachineApplicable,
);
}
}

fn report_use_of_uninitialized(
&self,
mpi: MovePathIndex,
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&mut err,
);

self.suggest_deref_unwrap_or(
&mut err,
error_span,
callee_ty,
call_ident,
expected_ty,
provided_ty,
provided_args[*provided_idx],
is_method,
);

// Call out where the function is defined
self.label_fn_like(
&mut err,
Expand Down
68 changes: 68 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1429,6 +1429,74 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
true
}

// Suggest to change `Option<&Vec<T>>::unwrap_or(&[])` to `Option::map_or(&[], |v| v)`.
#[instrument(level = "trace", skip(self, err, provided_expr))]
pub(crate) fn suggest_deref_unwrap_or(
&self,
err: &mut Diag<'_>,
error_span: Span,
callee_ty: Option<Ty<'tcx>>,
call_ident: Option<Ident>,
expected_ty: Ty<'tcx>,
provided_ty: Ty<'tcx>,
provided_expr: &Expr<'tcx>,
is_method: bool,
) {
if !is_method {
return;
}
let Some(callee_ty) = callee_ty else {
return;
};
let ty::Adt(callee_adt, _) = callee_ty.peel_refs().kind() else {
return;
};
let adt_name = if self.tcx.is_diagnostic_item(sym::Option, callee_adt.did()) {
"Option"
} else if self.tcx.is_diagnostic_item(sym::Result, callee_adt.did()) {
"Result"
} else {
return;
};

let Some(call_ident) = call_ident else {
return;
};
if call_ident.name != sym::unwrap_or {
return;
}

let ty::Ref(_, peeled, _mutability) = provided_ty.kind() else {
return;
};

// NOTE: Can we reuse `suggest_deref_or_ref`?

// Create an dummy type `&[_]` so that both &[] and `&Vec<T>` can coerce to it.
let dummy_ty = if let ty::Array(elem_ty, size) = peeled.kind()
&& let ty::Infer(_) = elem_ty.kind()
&& size.try_eval_target_usize(self.tcx, self.param_env) == Some(0)
{
let slice = Ty::new_slice(self.tcx, *elem_ty);
Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_static, slice)
} else {
provided_ty
};

if !self.can_coerce(expected_ty, dummy_ty) {
return;
}
let msg = format!("use `{adt_name}::map_or` to deref inner value of `{adt_name}`");
err.multipart_suggestion_verbose(
msg,
vec![
(call_ident.span, "map_or".to_owned()),
(provided_expr.span.shrink_to_hi(), ", |v| v".to_owned()),
],
Applicability::MachineApplicable,
);
}

/// Suggest wrapping the block in square brackets instead of curly braces
/// in case the block was mistaken array syntax, e.g. `{ 1 }` -> `[ 1 ]`.
pub(crate) fn suggest_block_to_brackets(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3810,6 +3810,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
{
if let Some(where_pred) = where_pred.as_trait_clause()
&& let Some(failed_pred) = failed_pred.as_trait_clause()
&& where_pred.def_id() == failed_pred.def_id()
{
self.enter_forall(where_pred, |where_pred| {
let failed_pred = self.instantiate_binder_with_fresh_vars(
Expand Down
6 changes: 3 additions & 3 deletions library/core/src/num/f128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,15 +170,15 @@ impl f128 {
/// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
/// [`MANTISSA_DIGITS`]: f128::MANTISSA_DIGITS
#[unstable(feature = "f128", issue = "116909")]
pub const EPSILON: f128 = 1.92592994438723585305597794258492731e-34_f128;
pub const EPSILON: f128 = 1.92592994438723585305597794258492732e-34_f128;

/// Smallest finite `f128` value.
///
/// Equal to &minus;[`MAX`].
///
/// [`MAX`]: f128::MAX
#[unstable(feature = "f128", issue = "116909")]
pub const MIN: f128 = -1.18973149535723176508575932662800701e+4932_f128;
pub const MIN: f128 = -1.18973149535723176508575932662800702e+4932_f128;
/// Smallest positive normal `f128` value.
///
/// Equal to 2<sup>[`MIN_EXP`]&nbsp;&minus;&nbsp;1</sup>.
Expand All @@ -194,7 +194,7 @@ impl f128 {
/// [`MANTISSA_DIGITS`]: f128::MANTISSA_DIGITS
/// [`MAX_EXP`]: f128::MAX_EXP
#[unstable(feature = "f128", issue = "116909")]
pub const MAX: f128 = 1.18973149535723176508575932662800701e+4932_f128;
pub const MAX: f128 = 1.18973149535723176508575932662800702e+4932_f128;

/// One greater than the minimum possible normal power of 2 exponent.
///
Expand Down
2 changes: 1 addition & 1 deletion src/doc/book
Submodule book updated 47 files
+4 −4 .github/workflows/main.yml
+3 −0 book.toml
+1 −0 ci/dictionary.txt
+1 −1 listings/ch02-guessing-game-tutorial/listing-02-04/output.txt
+2 −2 listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/output.txt
+2 −2 listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt
+1 −19 listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/output.txt
+1 −3 listings/ch11-writing-automated-tests/listing-11-03/src/lib.rs
+0 −2 listings/ch11-writing-automated-tests/listing-11-05/src/lib.rs
+3 −2 listings/ch11-writing-automated-tests/listing-11-07/src/lib.rs
+2 −2 listings/ch11-writing-automated-tests/listing-11-10/output.txt
+2 −2 listings/ch11-writing-automated-tests/listing-11-10/src/lib.rs
+7 −4 listings/ch11-writing-automated-tests/listing-11-11/src/lib.rs
+5 −4 listings/ch11-writing-automated-tests/listing-11-12/src/lib.rs
+5 −4 listings/ch11-writing-automated-tests/listing-11-13/src/lib.rs
+2 −1 listings/ch11-writing-automated-tests/listing-11-13/tests/integration_test.rs
+1 −0 listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt
+3 −2 listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/src/lib.rs
+1 −2 listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/src/lib.rs
+11 −1 listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/src/lib.rs
+2 −2 listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/output.txt
+19 −7 listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/src/lib.rs
+5 −4 listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/src/lib.rs
+3 −2 listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/tests/integration_test.rs
+5 −4 listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/src/lib.rs
+4 −2 listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/tests/integration_test.rs
+5 −4 listings/ch11-writing-automated-tests/output-only-05-single-integration/src/lib.rs
+3 −2 listings/ch11-writing-automated-tests/output-only-05-single-integration/tests/integration_test.rs
+2 −0 listings/ch13-functional-features/listing-13-04/output.txt
+2 −0 listings/ch13-functional-features/listing-13-05/output.txt
+5 −0 listings/ch13-functional-features/listing-13-08/output.txt
+7 −3 listings/ch15-smart-pointers/listing-15-21/output.txt
+0 −4 listings/ch16-fearless-concurrency/listing-16-09/output.txt
+10 −0 listings/ch16-fearless-concurrency/listing-16-13/output.txt
+1 −1 listings/ch16-fearless-concurrency/listing-16-14/output.txt
+2 −0 listings/ch19-advanced-features/listing-19-05/output.txt
+6 −0 listings/ch20-web-server/listing-20-17/output.txt
+1 −1 listings/ch20-web-server/listing-20-22/output.txt
+1 −1 listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt
+531 −358 nostarch/chapter11.md
+5 −1 packages/tools/src/bin/link2print.rs
+1 −1 rust-toolchain
+6 −5 src/ch11-00-testing.md
+52 −43 src/ch11-01-writing-tests.md
+14 −14 src/ch11-02-running-tests.md
+26 −31 src/ch11-03-test-organization.md
+1 −1 src/title-page.md
2 changes: 1 addition & 1 deletion src/doc/edition-guide
2 changes: 1 addition & 1 deletion src/doc/embedded-book
2 changes: 1 addition & 1 deletion src/doc/rust-by-example
20 changes: 0 additions & 20 deletions tests/crashes/126416.rs

This file was deleted.

68 changes: 68 additions & 0 deletions tests/ui/borrowck/dbg-issue-120327.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
fn s() -> String {
let a = String::new();
dbg!(a);
return a; //~ ERROR use of moved value:
}

fn m() -> String {
let a = String::new();
dbg!(1, 2, a, 1, 2);
return a; //~ ERROR use of moved value:
}

fn t(a: String) -> String {
let b: String = "".to_string();
dbg!(a, b);
return b; //~ ERROR use of moved value:
}

fn x(a: String) -> String {
let b: String = "".to_string();
dbg!(a, b);
return a; //~ ERROR use of moved value:
}

macro_rules! my_dbg {
() => {
eprintln!("[{}:{}:{}]", file!(), line!(), column!())
};
($val:expr $(,)?) => {
match $val {
tmp => {
eprintln!("[{}:{}:{}] {} = {:#?}",
file!(), line!(), column!(), stringify!($val), &tmp);
tmp
}
}
};
($($val:expr),+ $(,)?) => {
($(my_dbg!($val)),+,)
};
}

fn test_my_dbg() -> String {
let b: String = "".to_string();
my_dbg!(b, 1);
return b; //~ ERROR use of moved value:
}

fn test_not_macro() -> String {
let a = String::new();
let _b = match a {
tmp => {
eprintln!("dbg: {}", tmp);
tmp
}
};
return a; //~ ERROR use of moved value:
}

fn get_expr(_s: String) {}

fn test() {
let a: String = "".to_string();
let _res = get_expr(dbg!(a));
let _l = a.len(); //~ ERROR borrow of moved value
}

fn main() {}
Loading
Loading