Skip to content

Commit 66fe5d3

Browse files
authored
Rollup merge of rust-lang#102184 - chenyukang:fix-102087-add-binding-sugg, r=nagisa
Suggest Default::default() when binding isn't initialized Fixes rust-lang#102087
2 parents 6aa4656 + 21b9222 commit 66fe5d3

37 files changed

+504
-0
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+70
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
369369
let mut visitor = ConditionVisitor { spans: &spans, name: &name, errors: vec![] };
370370
visitor.visit_body(&body);
371371

372+
let mut show_assign_sugg = false;
372373
let isnt_initialized = if let InitializationRequiringAction::PartialAssignment
373374
| InitializationRequiringAction::Assignment = desired_action
374375
{
@@ -396,6 +397,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
396397
.count()
397398
== 0
398399
{
400+
show_assign_sugg = true;
399401
"isn't initialized"
400402
} else {
401403
"is possibly-uninitialized"
@@ -446,10 +448,78 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
446448
}
447449
}
448450
}
451+
449452
err.span_label(decl_span, "binding declared here but left uninitialized");
453+
if show_assign_sugg {
454+
struct LetVisitor {
455+
decl_span: Span,
456+
sugg_span: Option<Span>,
457+
}
458+
459+
impl<'v> Visitor<'v> for LetVisitor {
460+
fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) {
461+
if self.sugg_span.is_some() {
462+
return;
463+
}
464+
if let hir::StmtKind::Local(hir::Local {
465+
span, ty, init: None, ..
466+
}) = &ex.kind && span.contains(self.decl_span) {
467+
self.sugg_span = ty.map_or(Some(self.decl_span), |ty| Some(ty.span));
468+
}
469+
hir::intravisit::walk_stmt(self, ex);
470+
}
471+
}
472+
473+
let mut visitor = LetVisitor { decl_span, sugg_span: None };
474+
visitor.visit_body(&body);
475+
if let Some(span) = visitor.sugg_span {
476+
self.suggest_assign_value(&mut err, moved_place, span);
477+
}
478+
}
450479
err
451480
}
452481

482+
fn suggest_assign_value(
483+
&self,
484+
err: &mut Diagnostic,
485+
moved_place: PlaceRef<'tcx>,
486+
sugg_span: Span,
487+
) {
488+
let ty = moved_place.ty(self.body, self.infcx.tcx).ty;
489+
debug!("ty: {:?}, kind: {:?}", ty, ty.kind());
490+
491+
let tcx = self.infcx.tcx;
492+
let implements_default = |ty, param_env| {
493+
let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else {
494+
return false;
495+
};
496+
tcx.infer_ctxt().enter(|infcx| {
497+
infcx
498+
.type_implements_trait(default_trait, ty, ty::List::empty(), param_env)
499+
.may_apply()
500+
})
501+
};
502+
503+
let assign_value = match ty.kind() {
504+
ty::Bool => "false",
505+
ty::Float(_) => "0.0",
506+
ty::Int(_) | ty::Uint(_) => "0",
507+
ty::Never | ty::Error(_) => "",
508+
ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Vec) => "vec![]",
509+
ty::Adt(_, _) if implements_default(ty, self.param_env) => "Default::default()",
510+
_ => "todo!()",
511+
};
512+
513+
if !assign_value.is_empty() {
514+
err.span_suggestion_verbose(
515+
sugg_span.shrink_to_hi(),
516+
format!("consider assigning a value"),
517+
format!(" = {}", assign_value),
518+
Applicability::MaybeIncorrect,
519+
);
520+
}
521+
}
522+
453523
fn suggest_borrow_fn_like(
454524
&self,
455525
err: &mut Diagnostic,

src/test/ui/asm/x86_64/type-check-5.stderr

+10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ LL | let x: u64;
55
| - binding declared here but left uninitialized
66
LL | asm!("{}", in(reg) x);
77
| ^ `x` used here but it isn't initialized
8+
|
9+
help: consider assigning a value
10+
|
11+
LL | let x: u64 = 0;
12+
| +++
813

914
error[E0381]: used binding `y` isn't initialized
1015
--> $DIR/type-check-5.rs:18:9
@@ -13,6 +18,11 @@ LL | let mut y: u64;
1318
| ----- binding declared here but left uninitialized
1419
LL | asm!("{}", inout(reg) y);
1520
| ^^^^^^^^^^^^^^^^^^^^^^^^ `y` used here but it isn't initialized
21+
|
22+
help: consider assigning a value
23+
|
24+
LL | let mut y: u64 = 0;
25+
| +++
1626

1727
error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
1828
--> $DIR/type-check-5.rs:26:29

src/test/ui/borrowck/borrowck-block-unint.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ LL | force(|| {
77
| ^^ `x` used here but it isn't initialized
88
LL | println!("{}", x);
99
| - borrow occurs due to use in closure
10+
|
11+
help: consider assigning a value
12+
|
13+
LL | let x: isize = 0;
14+
| +++
1015

1116
error: aborting due to previous error
1217

src/test/ui/borrowck/borrowck-break-uninit-2.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ LL | println!("{}", x);
88
| ^ `x` used here but it isn't initialized
99
|
1010
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
11+
help: consider assigning a value
12+
|
13+
LL | let x: isize = 0;
14+
| +++
1115

1216
error: aborting due to previous error
1317

src/test/ui/borrowck/borrowck-break-uninit.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ LL | println!("{}", x);
88
| ^ `x` used here but it isn't initialized
99
|
1010
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
11+
help: consider assigning a value
12+
|
13+
LL | let x: isize = 0;
14+
| +++
1115

1216
error: aborting due to previous error
1317

src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ LL | let i: isize;
55
| - binding declared here but left uninitialized
66
LL | i
77
| ^ `i` used here but it isn't initialized
8+
|
9+
help: consider assigning a value
10+
|
11+
LL | let i: isize = 0;
12+
| +++
813

914
error: aborting due to previous error
1015

src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ LL | let i: isize;
55
| - binding declared here but left uninitialized
66
LL | i
77
| ^ `i` used here but it isn't initialized
8+
|
9+
help: consider assigning a value
10+
|
11+
LL | let i: isize = 0;
12+
| +++
813

914
error: aborting due to previous error
1015

src/test/ui/borrowck/borrowck-init-in-fru.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ LL | let mut origin: Point;
55
| ---------- binding declared here but left uninitialized
66
LL | origin = Point { x: 10, ..origin };
77
| ^^^^^^^^^^^^^^^^^^^^^^^^^ `origin.y` used here but it isn't initialized
8+
|
9+
help: consider assigning a value
10+
|
11+
LL | let mut origin: Point = todo!();
12+
| +++++++++
813

914
error: aborting due to previous error
1015

src/test/ui/borrowck/borrowck-init-op-equal.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ LL | let v: isize;
55
| - binding declared here but left uninitialized
66
LL | v += 1;
77
| ^^^^^^ `v` used here but it isn't initialized
8+
|
9+
help: consider assigning a value
10+
|
11+
LL | let v: isize = 0;
12+
| +++
813

914
error: aborting due to previous error
1015

src/test/ui/borrowck/borrowck-init-plus-equal.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ LL | let mut v: isize;
55
| ----- binding declared here but left uninitialized
66
LL | v = v + 1;
77
| ^ `v` used here but it isn't initialized
8+
|
9+
help: consider assigning a value
10+
|
11+
LL | let mut v: isize = 0;
12+
| +++
813

914
error: aborting due to previous error
1015

src/test/ui/borrowck/borrowck-return.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ LL | let x: isize;
55
| - binding declared here but left uninitialized
66
LL | return x;
77
| ^ `x` used here but it isn't initialized
8+
|
9+
help: consider assigning a value
10+
|
11+
LL | let x: isize = 0;
12+
| +++
813

914
error: aborting due to previous error
1015

src/test/ui/borrowck/borrowck-storage-dead.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ LL | let x: i32;
55
| - binding declared here but left uninitialized
66
LL | let _ = x + 1;
77
| ^ `x` used here but it isn't initialized
8+
|
9+
help: consider assigning a value
10+
|
11+
LL | let x: i32 = 0;
12+
| +++
813

914
error: aborting due to previous error
1015

src/test/ui/borrowck/borrowck-uninit-after-item.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ LL | let bar;
66
LL | fn baz(_x: isize) { }
77
LL | baz(bar);
88
| ^^^ `bar` used here but it isn't initialized
9+
|
10+
help: consider assigning a value
11+
|
12+
LL | let bar = 0;
13+
| +++
914

1015
error: aborting due to previous error
1116

src/test/ui/borrowck/borrowck-uninit-field-access.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ LL | let mut a: Point;
55
| ----- binding declared here but left uninitialized
66
LL | let _ = a.x + 1;
77
| ^^^ `a.x` used here but it isn't initialized
8+
|
9+
help: consider assigning a value
10+
|
11+
LL | let mut a: Point = Default::default();
12+
| ++++++++++++++++++++
813

914
error[E0382]: use of moved value: `line1.origin`
1015
--> $DIR/borrowck-uninit-field-access.rs:25:13

src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr

+50
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ LL | let x: isize;
55
| - binding declared here but left uninitialized
66
LL | x += 1;
77
| ^^^^^^ `x` used here but it isn't initialized
8+
|
9+
help: consider assigning a value
10+
|
11+
LL | let x: isize = 0;
12+
| +++
813

914
error[E0381]: used binding `x` isn't initialized
1015
--> $DIR/borrowck-uninit-in-assignop.rs:9:5
@@ -13,6 +18,11 @@ LL | let x: isize;
1318
| - binding declared here but left uninitialized
1419
LL | x -= 1;
1520
| ^^^^^^ `x` used here but it isn't initialized
21+
|
22+
help: consider assigning a value
23+
|
24+
LL | let x: isize = 0;
25+
| +++
1626

1727
error[E0381]: used binding `x` isn't initialized
1828
--> $DIR/borrowck-uninit-in-assignop.rs:12:5
@@ -21,6 +31,11 @@ LL | let x: isize;
2131
| - binding declared here but left uninitialized
2232
LL | x *= 1;
2333
| ^^^^^^ `x` used here but it isn't initialized
34+
|
35+
help: consider assigning a value
36+
|
37+
LL | let x: isize = 0;
38+
| +++
2439

2540
error[E0381]: used binding `x` isn't initialized
2641
--> $DIR/borrowck-uninit-in-assignop.rs:15:5
@@ -29,6 +44,11 @@ LL | let x: isize;
2944
| - binding declared here but left uninitialized
3045
LL | x /= 1;
3146
| ^^^^^^ `x` used here but it isn't initialized
47+
|
48+
help: consider assigning a value
49+
|
50+
LL | let x: isize = 0;
51+
| +++
3252

3353
error[E0381]: used binding `x` isn't initialized
3454
--> $DIR/borrowck-uninit-in-assignop.rs:18:5
@@ -37,6 +57,11 @@ LL | let x: isize;
3757
| - binding declared here but left uninitialized
3858
LL | x %= 1;
3959
| ^^^^^^ `x` used here but it isn't initialized
60+
|
61+
help: consider assigning a value
62+
|
63+
LL | let x: isize = 0;
64+
| +++
4065

4166
error[E0381]: used binding `x` isn't initialized
4267
--> $DIR/borrowck-uninit-in-assignop.rs:21:5
@@ -45,6 +70,11 @@ LL | let x: isize;
4570
| - binding declared here but left uninitialized
4671
LL | x ^= 1;
4772
| ^^^^^^ `x` used here but it isn't initialized
73+
|
74+
help: consider assigning a value
75+
|
76+
LL | let x: isize = 0;
77+
| +++
4878

4979
error[E0381]: used binding `x` isn't initialized
5080
--> $DIR/borrowck-uninit-in-assignop.rs:24:5
@@ -53,6 +83,11 @@ LL | let x: isize;
5383
| - binding declared here but left uninitialized
5484
LL | x &= 1;
5585
| ^^^^^^ `x` used here but it isn't initialized
86+
|
87+
help: consider assigning a value
88+
|
89+
LL | let x: isize = 0;
90+
| +++
5691

5792
error[E0381]: used binding `x` isn't initialized
5893
--> $DIR/borrowck-uninit-in-assignop.rs:27:5
@@ -61,6 +96,11 @@ LL | let x: isize;
6196
| - binding declared here but left uninitialized
6297
LL | x |= 1;
6398
| ^^^^^^ `x` used here but it isn't initialized
99+
|
100+
help: consider assigning a value
101+
|
102+
LL | let x: isize = 0;
103+
| +++
64104

65105
error[E0381]: used binding `x` isn't initialized
66106
--> $DIR/borrowck-uninit-in-assignop.rs:30:5
@@ -69,6 +109,11 @@ LL | let x: isize;
69109
| - binding declared here but left uninitialized
70110
LL | x <<= 1;
71111
| ^^^^^^^ `x` used here but it isn't initialized
112+
|
113+
help: consider assigning a value
114+
|
115+
LL | let x: isize = 0;
116+
| +++
72117

73118
error[E0381]: used binding `x` isn't initialized
74119
--> $DIR/borrowck-uninit-in-assignop.rs:33:5
@@ -77,6 +122,11 @@ LL | let x: isize;
77122
| - binding declared here but left uninitialized
78123
LL | x >>= 1;
79124
| ^^^^^^^ `x` used here but it isn't initialized
125+
|
126+
help: consider assigning a value
127+
|
128+
LL | let x: isize = 0;
129+
| +++
80130

81131
error: aborting due to 10 previous errors
82132

0 commit comments

Comments
 (0)