Skip to content

Commit 46eeec2

Browse files
authored
Unrolled build for rust-lang#120990
Rollup merge of rust-lang#120990 - chenyukang:yukang-fix-120327-dbg, r=oli-obk Suggest a borrow when using dbg Fixes rust-lang#120327 r? ````@estebank````
2 parents 2823cfb + 3179526 commit 46eeec2

File tree

4 files changed

+252
-2
lines changed

4 files changed

+252
-2
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,

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() {}
+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
error[E0382]: use of moved value: `a`
2+
--> $DIR/dbg-issue-120327.rs:4:12
3+
|
4+
LL | let a = String::new();
5+
| - move occurs because `a` has type `String`, which does not implement the `Copy` trait
6+
LL | dbg!(a);
7+
| ------- value moved here
8+
LL | return a;
9+
| ^ value used here after move
10+
|
11+
help: consider borrowing instead of transferring ownership
12+
|
13+
LL | dbg!(&a);
14+
| +
15+
16+
error[E0382]: use of moved value: `a`
17+
--> $DIR/dbg-issue-120327.rs:10:12
18+
|
19+
LL | let a = String::new();
20+
| - move occurs because `a` has type `String`, which does not implement the `Copy` trait
21+
LL | dbg!(1, 2, a, 1, 2);
22+
| ------------------- value moved here
23+
LL | return a;
24+
| ^ value used here after move
25+
|
26+
help: consider borrowing instead of transferring ownership
27+
|
28+
LL | dbg!(1, 2, &a, 1, 2);
29+
| +
30+
31+
error[E0382]: use of moved value: `b`
32+
--> $DIR/dbg-issue-120327.rs:16:12
33+
|
34+
LL | let b: String = "".to_string();
35+
| - move occurs because `b` has type `String`, which does not implement the `Copy` trait
36+
LL | dbg!(a, b);
37+
| ---------- value moved here
38+
LL | return b;
39+
| ^ value used here after move
40+
|
41+
help: consider borrowing instead of transferring ownership
42+
|
43+
LL | dbg!(a, &b);
44+
| +
45+
46+
error[E0382]: use of moved value: `a`
47+
--> $DIR/dbg-issue-120327.rs:22:12
48+
|
49+
LL | fn x(a: String) -> String {
50+
| - move occurs because `a` has type `String`, which does not implement the `Copy` trait
51+
LL | let b: String = "".to_string();
52+
LL | dbg!(a, b);
53+
| ---------- value moved here
54+
LL | return a;
55+
| ^ value used here after move
56+
|
57+
help: consider borrowing instead of transferring ownership
58+
|
59+
LL | dbg!(&a, b);
60+
| +
61+
62+
error[E0382]: use of moved value: `b`
63+
--> $DIR/dbg-issue-120327.rs:46:12
64+
|
65+
LL | tmp => {
66+
| --- value moved here
67+
...
68+
LL | let b: String = "".to_string();
69+
| - move occurs because `b` has type `String`, which does not implement the `Copy` trait
70+
LL | my_dbg!(b, 1);
71+
LL | return b;
72+
| ^ value used here after move
73+
|
74+
help: consider borrowing instead of transferring ownership
75+
|
76+
LL | my_dbg!(&b, 1);
77+
| +
78+
help: borrow this binding in the pattern to avoid moving the value
79+
|
80+
LL | ref tmp => {
81+
| +++
82+
83+
error[E0382]: use of moved value: `a`
84+
--> $DIR/dbg-issue-120327.rs:57:12
85+
|
86+
LL | let a = String::new();
87+
| - move occurs because `a` has type `String`, which does not implement the `Copy` trait
88+
LL | let _b = match a {
89+
LL | tmp => {
90+
| --- value moved here
91+
...
92+
LL | return a;
93+
| ^ value used here after move
94+
|
95+
help: borrow this binding in the pattern to avoid moving the value
96+
|
97+
LL | ref tmp => {
98+
| +++
99+
100+
error[E0382]: borrow of moved value: `a`
101+
--> $DIR/dbg-issue-120327.rs:65:14
102+
|
103+
LL | let a: String = "".to_string();
104+
| - move occurs because `a` has type `String`, which does not implement the `Copy` trait
105+
LL | let _res = get_expr(dbg!(a));
106+
| ------- value moved here
107+
LL | let _l = a.len();
108+
| ^ value borrowed here after move
109+
|
110+
help: consider borrowing instead of transferring ownership
111+
|
112+
LL | let _res = get_expr(dbg!(&a));
113+
| +
114+
115+
error: aborting due to 7 previous errors
116+
117+
For more information about this error, try `rustc --explain E0382`.

tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ LL | let _ = dbg!(a);
99
| ^^^^^^^ value used here after move
1010
|
1111
= note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
12+
help: consider borrowing instead of transferring ownership
13+
|
14+
LL | let _ = dbg!(&a);
15+
| +
1216

1317
error: aborting due to 1 previous error
1418

0 commit comments

Comments
 (0)