Skip to content

Commit 8cf1348

Browse files
committed
Auto merge of #127785 - matthiaskrgr:rollup-04q3ug0, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #120990 (Suggest a borrow when using dbg) - #127047 (fix least significant digits of f128 associated constants) - #127629 (Suggest using `map_or` when `Option<&T>::unwrap_or where T: Deref` fails) - #127770 (Update books) - #127780 (Make sure trait def ids match before zipping args in `note_function_argument_obligation`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 24d2ac0 + 793d1c3 commit 8cf1348

File tree

19 files changed

+523
-32
lines changed

19 files changed

+523
-32
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+63-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#![allow(rustc::untranslatable_diagnostic)]
55

66
use either::Either;
7-
use hir::ClosureKind;
7+
use hir::{ClosureKind, Path};
88
use rustc_data_structures::captures::Captures;
99
use rustc_data_structures::fx::FxIndexSet;
1010
use rustc_errors::{codes::*, struct_span_code_err, Applicability, Diag, MultiSpan};
@@ -16,6 +16,7 @@ use rustc_hir::{CoroutineKind, CoroutineSource, LangItem};
1616
use rustc_middle::bug;
1717
use rustc_middle::hir::nested_filter::OnlyBodies;
1818
use rustc_middle::mir::tcx::PlaceTy;
19+
use rustc_middle::mir::VarDebugInfoContents;
1920
use rustc_middle::mir::{
2021
self, AggregateKind, BindingForm, BorrowKind, CallSource, ClearCrossCrate, ConstraintCategory,
2122
FakeBorrowKind, FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, MutBorrowKind,
@@ -546,7 +547,14 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
546547
self.suggest_cloning(err, ty, expr, None, Some(move_spans));
547548
}
548549
}
549-
if let Some(pat) = finder.pat {
550+
551+
self.suggest_ref_for_dbg_args(expr, place, move_span, err);
552+
553+
// it's useless to suggest inserting `ref` when the span don't comes from local code
554+
if let Some(pat) = finder.pat
555+
&& !move_span.is_dummy()
556+
&& !self.infcx.tcx.sess.source_map().is_imported(move_span)
557+
{
550558
*in_pattern = true;
551559
let mut sugg = vec![(pat.span.shrink_to_lo(), "ref ".to_string())];
552560
if let Some(pat) = finder.parent_pat {
@@ -561,6 +569,59 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
561569
}
562570
}
563571

572+
// for dbg!(x) which may take ownership, suggest dbg!(&x) instead
573+
// but here we actually do not check whether the macro name is `dbg!`
574+
// so that we may extend the scope a bit larger to cover more cases
575+
fn suggest_ref_for_dbg_args(
576+
&self,
577+
body: &hir::Expr<'_>,
578+
place: &Place<'tcx>,
579+
move_span: Span,
580+
err: &mut Diag<'infcx>,
581+
) {
582+
let var_info = self.body.var_debug_info.iter().find(|info| match info.value {
583+
VarDebugInfoContents::Place(ref p) => p == place,
584+
_ => false,
585+
});
586+
let arg_name = if let Some(var_info) = var_info {
587+
var_info.name
588+
} else {
589+
return;
590+
};
591+
struct MatchArgFinder {
592+
expr_span: Span,
593+
match_arg_span: Option<Span>,
594+
arg_name: Symbol,
595+
}
596+
impl Visitor<'_> for MatchArgFinder {
597+
fn visit_expr(&mut self, e: &hir::Expr<'_>) {
598+
// dbg! is expanded into a match pattern, we need to find the right argument span
599+
if let hir::ExprKind::Match(expr, ..) = &e.kind
600+
&& let hir::ExprKind::Path(hir::QPath::Resolved(
601+
_,
602+
path @ Path { segments: [seg], .. },
603+
)) = &expr.kind
604+
&& seg.ident.name == self.arg_name
605+
&& self.expr_span.source_callsite().contains(expr.span)
606+
{
607+
self.match_arg_span = Some(path.span);
608+
}
609+
hir::intravisit::walk_expr(self, e);
610+
}
611+
}
612+
613+
let mut finder = MatchArgFinder { expr_span: move_span, match_arg_span: None, arg_name };
614+
finder.visit_expr(body);
615+
if let Some(macro_arg_span) = finder.match_arg_span {
616+
err.span_suggestion_verbose(
617+
macro_arg_span.shrink_to_lo(),
618+
"consider borrowing instead of transferring ownership",
619+
"&",
620+
Applicability::MachineApplicable,
621+
);
622+
}
623+
}
624+
564625
fn report_use_of_uninitialized(
565626
&self,
566627
mpi: MovePathIndex,

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+11
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
948948
&mut err,
949949
);
950950

951+
self.suggest_deref_unwrap_or(
952+
&mut err,
953+
error_span,
954+
callee_ty,
955+
call_ident,
956+
expected_ty,
957+
provided_ty,
958+
provided_args[*provided_idx],
959+
is_method,
960+
);
961+
951962
// Call out where the function is defined
952963
self.label_fn_like(
953964
&mut err,

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+68
Original file line numberDiff line numberDiff line change
@@ -1429,6 +1429,74 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14291429
true
14301430
}
14311431

1432+
// Suggest to change `Option<&Vec<T>>::unwrap_or(&[])` to `Option::map_or(&[], |v| v)`.
1433+
#[instrument(level = "trace", skip(self, err, provided_expr))]
1434+
pub(crate) fn suggest_deref_unwrap_or(
1435+
&self,
1436+
err: &mut Diag<'_>,
1437+
error_span: Span,
1438+
callee_ty: Option<Ty<'tcx>>,
1439+
call_ident: Option<Ident>,
1440+
expected_ty: Ty<'tcx>,
1441+
provided_ty: Ty<'tcx>,
1442+
provided_expr: &Expr<'tcx>,
1443+
is_method: bool,
1444+
) {
1445+
if !is_method {
1446+
return;
1447+
}
1448+
let Some(callee_ty) = callee_ty else {
1449+
return;
1450+
};
1451+
let ty::Adt(callee_adt, _) = callee_ty.peel_refs().kind() else {
1452+
return;
1453+
};
1454+
let adt_name = if self.tcx.is_diagnostic_item(sym::Option, callee_adt.did()) {
1455+
"Option"
1456+
} else if self.tcx.is_diagnostic_item(sym::Result, callee_adt.did()) {
1457+
"Result"
1458+
} else {
1459+
return;
1460+
};
1461+
1462+
let Some(call_ident) = call_ident else {
1463+
return;
1464+
};
1465+
if call_ident.name != sym::unwrap_or {
1466+
return;
1467+
}
1468+
1469+
let ty::Ref(_, peeled, _mutability) = provided_ty.kind() else {
1470+
return;
1471+
};
1472+
1473+
// NOTE: Can we reuse `suggest_deref_or_ref`?
1474+
1475+
// Create an dummy type `&[_]` so that both &[] and `&Vec<T>` can coerce to it.
1476+
let dummy_ty = if let ty::Array(elem_ty, size) = peeled.kind()
1477+
&& let ty::Infer(_) = elem_ty.kind()
1478+
&& size.try_eval_target_usize(self.tcx, self.param_env) == Some(0)
1479+
{
1480+
let slice = Ty::new_slice(self.tcx, *elem_ty);
1481+
Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_static, slice)
1482+
} else {
1483+
provided_ty
1484+
};
1485+
1486+
if !self.can_coerce(expected_ty, dummy_ty) {
1487+
return;
1488+
}
1489+
let msg = format!("use `{adt_name}::map_or` to deref inner value of `{adt_name}`");
1490+
err.multipart_suggestion_verbose(
1491+
msg,
1492+
vec![
1493+
(call_ident.span, "map_or".to_owned()),
1494+
(provided_expr.span.shrink_to_hi(), ", |v| v".to_owned()),
1495+
],
1496+
Applicability::MachineApplicable,
1497+
);
1498+
}
1499+
14321500
/// Suggest wrapping the block in square brackets instead of curly braces
14331501
/// in case the block was mistaken array syntax, e.g. `{ 1 }` -> `[ 1 ]`.
14341502
pub(crate) fn suggest_block_to_brackets(

compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3810,6 +3810,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
38103810
{
38113811
if let Some(where_pred) = where_pred.as_trait_clause()
38123812
&& let Some(failed_pred) = failed_pred.as_trait_clause()
3813+
&& where_pred.def_id() == failed_pred.def_id()
38133814
{
38143815
self.enter_forall(where_pred, |where_pred| {
38153816
let failed_pred = self.instantiate_binder_with_fresh_vars(

library/core/src/num/f128.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -170,15 +170,15 @@ impl f128 {
170170
/// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
171171
/// [`MANTISSA_DIGITS`]: f128::MANTISSA_DIGITS
172172
#[unstable(feature = "f128", issue = "116909")]
173-
pub const EPSILON: f128 = 1.92592994438723585305597794258492731e-34_f128;
173+
pub const EPSILON: f128 = 1.92592994438723585305597794258492732e-34_f128;
174174

175175
/// Smallest finite `f128` value.
176176
///
177177
/// Equal to &minus;[`MAX`].
178178
///
179179
/// [`MAX`]: f128::MAX
180180
#[unstable(feature = "f128", issue = "116909")]
181-
pub const MIN: f128 = -1.18973149535723176508575932662800701e+4932_f128;
181+
pub const MIN: f128 = -1.18973149535723176508575932662800702e+4932_f128;
182182
/// Smallest positive normal `f128` value.
183183
///
184184
/// Equal to 2<sup>[`MIN_EXP`]&nbsp;&minus;&nbsp;1</sup>.
@@ -194,7 +194,7 @@ impl f128 {
194194
/// [`MANTISSA_DIGITS`]: f128::MANTISSA_DIGITS
195195
/// [`MAX_EXP`]: f128::MAX_EXP
196196
#[unstable(feature = "f128", issue = "116909")]
197-
pub const MAX: f128 = 1.18973149535723176508575932662800701e+4932_f128;
197+
pub const MAX: f128 = 1.18973149535723176508575932662800702e+4932_f128;
198198

199199
/// One greater than the minimum possible normal power of 2 exponent.
200200
///

src/doc/book

Submodule book updated 47 files

src/doc/embedded-book

tests/crashes/126416.rs

-20
This file was deleted.

tests/ui/borrowck/dbg-issue-120327.rs

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
fn s() -> String {
2+
let a = String::new();
3+
dbg!(a);
4+
return a; //~ ERROR use of moved value:
5+
}
6+
7+
fn m() -> String {
8+
let a = String::new();
9+
dbg!(1, 2, a, 1, 2);
10+
return a; //~ ERROR use of moved value:
11+
}
12+
13+
fn t(a: String) -> String {
14+
let b: String = "".to_string();
15+
dbg!(a, b);
16+
return b; //~ ERROR use of moved value:
17+
}
18+
19+
fn x(a: String) -> String {
20+
let b: String = "".to_string();
21+
dbg!(a, b);
22+
return a; //~ ERROR use of moved value:
23+
}
24+
25+
macro_rules! my_dbg {
26+
() => {
27+
eprintln!("[{}:{}:{}]", file!(), line!(), column!())
28+
};
29+
($val:expr $(,)?) => {
30+
match $val {
31+
tmp => {
32+
eprintln!("[{}:{}:{}] {} = {:#?}",
33+
file!(), line!(), column!(), stringify!($val), &tmp);
34+
tmp
35+
}
36+
}
37+
};
38+
($($val:expr),+ $(,)?) => {
39+
($(my_dbg!($val)),+,)
40+
};
41+
}
42+
43+
fn test_my_dbg() -> String {
44+
let b: String = "".to_string();
45+
my_dbg!(b, 1);
46+
return b; //~ ERROR use of moved value:
47+
}
48+
49+
fn test_not_macro() -> String {
50+
let a = String::new();
51+
let _b = match a {
52+
tmp => {
53+
eprintln!("dbg: {}", tmp);
54+
tmp
55+
}
56+
};
57+
return a; //~ ERROR use of moved value:
58+
}
59+
60+
fn get_expr(_s: String) {}
61+
62+
fn test() {
63+
let a: String = "".to_string();
64+
let _res = get_expr(dbg!(a));
65+
let _l = a.len(); //~ ERROR borrow of moved value
66+
}
67+
68+
fn main() {}

0 commit comments

Comments
 (0)