Skip to content

Commit 8a2c0cc

Browse files
committed
fix #102087, Suggest Default::default() when binding isn't initialized
1 parent 11bb80a commit 8a2c0cc

37 files changed

+474
-0
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_middle::mir::{
1616
FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
1717
ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
1818
};
19+
//use rustc_middle::ty::subst::InternalSubsts;
1920
use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty};
2021
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
2122
use rustc_span::def_id::LocalDefId;
@@ -336,6 +337,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
336337
let inits = &self.move_data.init_path_map[mpi];
337338
let move_path = &self.move_data.move_paths[mpi];
338339
let decl_span = self.body.local_decls[move_path.place.local].source_info.span;
340+
339341
let mut spans = vec![];
340342
for init_idx in inits {
341343
let init = &self.move_data.inits[*init_idx];
@@ -369,6 +371,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
369371
let mut visitor = ConditionVisitor { spans: &spans, name: &name, errors: vec![] };
370372
visitor.visit_body(&body);
371373

374+
let mut show_assign_sugg = false;
372375
let isnt_initialized = if let InitializationRequiringAction::PartialAssignment
373376
| InitializationRequiringAction::Assignment = desired_action
374377
{
@@ -396,6 +399,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
396399
.count()
397400
== 0
398401
{
402+
show_assign_sugg = true;
399403
"isn't initialized"
400404
} else {
401405
"is possibly-uninitialized"
@@ -446,10 +450,69 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
446450
}
447451
}
448452
}
453+
449454
err.span_label(decl_span, "binding declared here but left uninitialized");
455+
if show_assign_sugg {
456+
self.suggest_assign_rvalue(&mut err, moved_place, &name, decl_span);
457+
}
450458
err
451459
}
452460

461+
fn suggest_assign_rvalue(
462+
&self,
463+
err: &mut Diagnostic,
464+
moved_place: PlaceRef<'tcx>,
465+
name: &str,
466+
decl_span: Span,
467+
) {
468+
let ty = moved_place.ty(self.body, self.infcx.tcx).ty;
469+
debug!("ty: {:?}, kind: {:?}", ty, ty.kind());
470+
471+
let initilize_msg = match ty.kind() {
472+
ty::Array(_, n) => format!("[val; {}]", n),
473+
ty::Int(_) | ty::Uint(_) => format!("0"),
474+
ty::Float(_) => format!("0.0"),
475+
ty::Bool => format!("false"),
476+
ty::Never | ty::Error(_) => "".to_string(),
477+
ty::Adt(def, _substs) => {
478+
if format!("{:?}", def).starts_with("std::vec::Vec") {
479+
format!("vec![]")
480+
} else if let Some(default_trait) = self.infcx.tcx.get_diagnostic_item(sym::Default) &&
481+
self.infcx.tcx.infer_ctxt().enter(|infcx| {
482+
infcx.type_implements_trait(default_trait, ty, ty::List::empty(), self.param_env).may_apply()
483+
}) {
484+
format!("Default::default()")
485+
} else {
486+
format!("something")
487+
}
488+
},
489+
_ => format!("something"),
490+
};
491+
492+
if initilize_msg.is_empty() {
493+
return;
494+
}
495+
496+
let sugg_span = self
497+
.infcx
498+
.tcx
499+
.sess
500+
.source_map()
501+
.span_extend_while(decl_span, |c| c != '\n')
502+
.unwrap_or(decl_span);
503+
let mut prefix = self.infcx.tcx.sess.source_map().span_to_snippet(sugg_span).unwrap();
504+
// remove last char if eq ';'
505+
if prefix.ends_with(';') {
506+
prefix.pop();
507+
}
508+
err.span_suggestion_verbose(
509+
sugg_span,
510+
format!("use `=` to assign some value to {}", name),
511+
format!("{} = {};", prefix, initilize_msg),
512+
Applicability::MaybeIncorrect,
513+
);
514+
}
515+
453516
fn suggest_borrow_fn_like(
454517
&self,
455518
err: &mut Diagnostic,

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

Lines changed: 10 additions & 0 deletions
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: use `=` to assign some value to `x`
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: use `=` to assign some value to `y`
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

Lines changed: 5 additions & 0 deletions
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: use `=` to assign some value to `x`
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

Lines changed: 4 additions & 0 deletions
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: use `=` to assign some value to `x`
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

Lines changed: 4 additions & 0 deletions
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: use `=` to assign some value to `x`
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

Lines changed: 5 additions & 0 deletions
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: use `=` to assign some value to `i`
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

Lines changed: 5 additions & 0 deletions
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: use `=` to assign some value to `i`
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

Lines changed: 5 additions & 0 deletions
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: use `=` to assign some value to `origin`
10+
|
11+
LL | let mut origin: Point = something;
12+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
813

914
error: aborting due to previous error
1015

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

Lines changed: 5 additions & 0 deletions
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: use `=` to assign some value to `v`
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

Lines changed: 5 additions & 0 deletions
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: use `=` to assign some value to `v`
10+
|
11+
LL | let mut v: isize = 0;
12+
| ~~~~~~~~~~~~~~~~~
813

914
error: aborting due to previous error
1015

0 commit comments

Comments
 (0)