Skip to content

Commit 84946fe

Browse files
committed
Auto 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 21265dd + 672e3f4 commit 84946fe

38 files changed

+514
-0
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

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

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

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

src/test/ui/asm/aarch64/type-check-2-2.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-2-2.rs:22: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-2-2.rs:30:29

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

0 commit comments

Comments
 (0)