Skip to content

Commit

Permalink
fix rust-lang#102087, Suggest Default::default() when binding isn't i…
Browse files Browse the repository at this point in the history
…nitialized
  • Loading branch information
chenyukang committed Sep 23, 2022
1 parent 11bb80a commit 8a2c0cc
Show file tree
Hide file tree
Showing 37 changed files with 474 additions and 0 deletions.
63 changes: 63 additions & 0 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use rustc_middle::mir::{
FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
};
//use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty};
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
use rustc_span::def_id::LocalDefId;
Expand Down Expand Up @@ -336,6 +337,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let inits = &self.move_data.init_path_map[mpi];
let move_path = &self.move_data.move_paths[mpi];
let decl_span = self.body.local_decls[move_path.place.local].source_info.span;

let mut spans = vec![];
for init_idx in inits {
let init = &self.move_data.inits[*init_idx];
Expand Down Expand Up @@ -369,6 +371,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let mut visitor = ConditionVisitor { spans: &spans, name: &name, errors: vec![] };
visitor.visit_body(&body);

let mut show_assign_sugg = false;
let isnt_initialized = if let InitializationRequiringAction::PartialAssignment
| InitializationRequiringAction::Assignment = desired_action
{
Expand Down Expand Up @@ -396,6 +399,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
.count()
== 0
{
show_assign_sugg = true;
"isn't initialized"
} else {
"is possibly-uninitialized"
Expand Down Expand Up @@ -446,10 +450,69 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}
}

err.span_label(decl_span, "binding declared here but left uninitialized");
if show_assign_sugg {
self.suggest_assign_rvalue(&mut err, moved_place, &name, decl_span);
}
err
}

fn suggest_assign_rvalue(
&self,
err: &mut Diagnostic,
moved_place: PlaceRef<'tcx>,
name: &str,
decl_span: Span,
) {
let ty = moved_place.ty(self.body, self.infcx.tcx).ty;
debug!("ty: {:?}, kind: {:?}", ty, ty.kind());

let initilize_msg = match ty.kind() {
ty::Array(_, n) => format!("[val; {}]", n),
ty::Int(_) | ty::Uint(_) => format!("0"),
ty::Float(_) => format!("0.0"),
ty::Bool => format!("false"),
ty::Never | ty::Error(_) => "".to_string(),
ty::Adt(def, _substs) => {
if format!("{:?}", def).starts_with("std::vec::Vec") {
format!("vec![]")
} else if let Some(default_trait) = self.infcx.tcx.get_diagnostic_item(sym::Default) &&
self.infcx.tcx.infer_ctxt().enter(|infcx| {
infcx.type_implements_trait(default_trait, ty, ty::List::empty(), self.param_env).may_apply()
}) {
format!("Default::default()")
} else {
format!("something")
}
},
_ => format!("something"),
};

if initilize_msg.is_empty() {
return;
}

let sugg_span = self
.infcx
.tcx
.sess
.source_map()
.span_extend_while(decl_span, |c| c != '\n')
.unwrap_or(decl_span);
let mut prefix = self.infcx.tcx.sess.source_map().span_to_snippet(sugg_span).unwrap();
// remove last char if eq ';'
if prefix.ends_with(';') {
prefix.pop();
}
err.span_suggestion_verbose(
sugg_span,
format!("use `=` to assign some value to {}", name),
format!("{} = {};", prefix, initilize_msg),
Applicability::MaybeIncorrect,
);
}

fn suggest_borrow_fn_like(
&self,
err: &mut Diagnostic,
Expand Down
10 changes: 10 additions & 0 deletions src/test/ui/asm/x86_64/type-check-5.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ LL | let x: u64;
| - binding declared here but left uninitialized
LL | asm!("{}", in(reg) x);
| ^ `x` used here but it isn't initialized
|
help: use `=` to assign some value to `x`
|
LL | let x: u64 = 0;
| ~~~~~~~~~~~

error[E0381]: used binding `y` isn't initialized
--> $DIR/type-check-5.rs:18:9
Expand All @@ -13,6 +18,11 @@ LL | let mut y: u64;
| ----- binding declared here but left uninitialized
LL | asm!("{}", inout(reg) y);
| ^^^^^^^^^^^^^^^^^^^^^^^^ `y` used here but it isn't initialized
|
help: use `=` to assign some value to `y`
|
LL | let mut y: u64 = 0;
| ~~~~~~~~~~~~~~~

error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
--> $DIR/type-check-5.rs:26:29
Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/borrowck/borrowck-block-unint.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ LL | force(|| {
| ^^ `x` used here but it isn't initialized
LL | println!("{}", x);
| - borrow occurs due to use in closure
|
help: use `=` to assign some value to `x`
|
LL | let x: isize = 0;
| ~~~~~~~~~~~~~

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/borrowck/borrowck-break-uninit-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | println!("{}", x);
| ^ `x` used here but it isn't initialized
|
= 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)
help: use `=` to assign some value to `x`
|
LL | let x: isize = 0;
| ~~~~~~~~~~~~~

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/borrowck/borrowck-break-uninit.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | println!("{}", x);
| ^ `x` used here but it isn't initialized
|
= 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)
help: use `=` to assign some value to `x`
|
LL | let x: isize = 0;
| ~~~~~~~~~~~~~

error: aborting due to previous error

Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ LL | let i: isize;
| - binding declared here but left uninitialized
LL | i
| ^ `i` used here but it isn't initialized
|
help: use `=` to assign some value to `i`
|
LL | let i: isize = 0;
| ~~~~~~~~~~~~~

error: aborting due to previous error

Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ LL | let i: isize;
| - binding declared here but left uninitialized
LL | i
| ^ `i` used here but it isn't initialized
|
help: use `=` to assign some value to `i`
|
LL | let i: isize = 0;
| ~~~~~~~~~~~~~

error: aborting due to previous error

Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/borrowck/borrowck-init-in-fru.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ LL | let mut origin: Point;
| ---------- binding declared here but left uninitialized
LL | origin = Point { x: 10, ..origin };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ `origin.y` used here but it isn't initialized
|
help: use `=` to assign some value to `origin`
|
LL | let mut origin: Point = something;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

error: aborting due to previous error

Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/borrowck/borrowck-init-op-equal.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ LL | let v: isize;
| - binding declared here but left uninitialized
LL | v += 1;
| ^^^^^^ `v` used here but it isn't initialized
|
help: use `=` to assign some value to `v`
|
LL | let v: isize = 0;
| ~~~~~~~~~~~~~

error: aborting due to previous error

Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/borrowck/borrowck-init-plus-equal.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ LL | let mut v: isize;
| ----- binding declared here but left uninitialized
LL | v = v + 1;
| ^ `v` used here but it isn't initialized
|
help: use `=` to assign some value to `v`
|
LL | let mut v: isize = 0;
| ~~~~~~~~~~~~~~~~~

error: aborting due to previous error

Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/borrowck/borrowck-return.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ LL | let x: isize;
| - binding declared here but left uninitialized
LL | return x;
| ^ `x` used here but it isn't initialized
|
help: use `=` to assign some value to `x`
|
LL | let x: isize = 0;
| ~~~~~~~~~~~~~

error: aborting due to previous error

Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/borrowck/borrowck-storage-dead.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ LL | let x: i32;
| - binding declared here but left uninitialized
LL | let _ = x + 1;
| ^ `x` used here but it isn't initialized
|
help: use `=` to assign some value to `x`
|
LL | let x: i32 = 0;
| ~~~~~~~~~~~

error: aborting due to previous error

Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/borrowck/borrowck-uninit-after-item.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ LL | let bar;
LL | fn baz(_x: isize) { }
LL | baz(bar);
| ^^^ `bar` used here but it isn't initialized
|
help: use `=` to assign some value to `bar`
|
LL | let bar = 0;
| ~~~~~~~~

error: aborting due to previous error

Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/borrowck/borrowck-uninit-field-access.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ LL | let mut a: Point;
| ----- binding declared here but left uninitialized
LL | let _ = a.x + 1;
| ^^^ `a.x` used here but it isn't initialized
|
help: use `=` to assign some value to `a`
|
LL | let mut a: Point = Default::default();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

error[E0382]: use of moved value: `line1.origin`
--> $DIR/borrowck-uninit-field-access.rs:25:13
Expand Down
50 changes: 50 additions & 0 deletions src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ LL | let x: isize;
| - binding declared here but left uninitialized
LL | x += 1;
| ^^^^^^ `x` used here but it isn't initialized
|
help: use `=` to assign some value to `x`
|
LL | let x: isize = 0;
| ~~~~~~~~~~~~~

error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:9:5
Expand All @@ -13,6 +18,11 @@ LL | let x: isize;
| - binding declared here but left uninitialized
LL | x -= 1;
| ^^^^^^ `x` used here but it isn't initialized
|
help: use `=` to assign some value to `x`
|
LL | let x: isize = 0;
| ~~~~~~~~~~~~~

error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:12:5
Expand All @@ -21,6 +31,11 @@ LL | let x: isize;
| - binding declared here but left uninitialized
LL | x *= 1;
| ^^^^^^ `x` used here but it isn't initialized
|
help: use `=` to assign some value to `x`
|
LL | let x: isize = 0;
| ~~~~~~~~~~~~~

error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:15:5
Expand All @@ -29,6 +44,11 @@ LL | let x: isize;
| - binding declared here but left uninitialized
LL | x /= 1;
| ^^^^^^ `x` used here but it isn't initialized
|
help: use `=` to assign some value to `x`
|
LL | let x: isize = 0;
| ~~~~~~~~~~~~~

error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:18:5
Expand All @@ -37,6 +57,11 @@ LL | let x: isize;
| - binding declared here but left uninitialized
LL | x %= 1;
| ^^^^^^ `x` used here but it isn't initialized
|
help: use `=` to assign some value to `x`
|
LL | let x: isize = 0;
| ~~~~~~~~~~~~~

error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:21:5
Expand All @@ -45,6 +70,11 @@ LL | let x: isize;
| - binding declared here but left uninitialized
LL | x ^= 1;
| ^^^^^^ `x` used here but it isn't initialized
|
help: use `=` to assign some value to `x`
|
LL | let x: isize = 0;
| ~~~~~~~~~~~~~

error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:24:5
Expand All @@ -53,6 +83,11 @@ LL | let x: isize;
| - binding declared here but left uninitialized
LL | x &= 1;
| ^^^^^^ `x` used here but it isn't initialized
|
help: use `=` to assign some value to `x`
|
LL | let x: isize = 0;
| ~~~~~~~~~~~~~

error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:27:5
Expand All @@ -61,6 +96,11 @@ LL | let x: isize;
| - binding declared here but left uninitialized
LL | x |= 1;
| ^^^^^^ `x` used here but it isn't initialized
|
help: use `=` to assign some value to `x`
|
LL | let x: isize = 0;
| ~~~~~~~~~~~~~

error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:30:5
Expand All @@ -69,6 +109,11 @@ LL | let x: isize;
| - binding declared here but left uninitialized
LL | x <<= 1;
| ^^^^^^^ `x` used here but it isn't initialized
|
help: use `=` to assign some value to `x`
|
LL | let x: isize = 0;
| ~~~~~~~~~~~~~

error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:33:5
Expand All @@ -77,6 +122,11 @@ LL | let x: isize;
| - binding declared here but left uninitialized
LL | x >>= 1;
| ^^^^^^^ `x` used here but it isn't initialized
|
help: use `=` to assign some value to `x`
|
LL | let x: isize = 0;
| ~~~~~~~~~~~~~

error: aborting due to 10 previous errors

Expand Down
Loading

0 comments on commit 8a2c0cc

Please sign in to comment.