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

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

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

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

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

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

Lines changed: 50 additions & 0 deletions
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: use `=` to assign some value to `x`
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: use `=` to assign some value to `x`
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: use `=` to assign some value to `x`
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: use `=` to assign some value to `x`
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: use `=` to assign some value to `x`
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: use `=` to assign some value to `x`
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: use `=` to assign some value to `x`
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: use `=` to assign some value to `x`
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: use `=` to assign some value to `x`
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: use `=` to assign some value to `x`
127+
|
128+
LL | let x: isize = 0;
129+
| ~~~~~~~~~~~~~
80130

81131
error: aborting due to 10 previous errors
82132

0 commit comments

Comments
 (0)