Skip to content

Commit 9e34c55

Browse files
committed
Auto merge of #154657 - chenyukang:yukang-fix-145564-pattern-assignment-help, r=<try>
Fix pattern assignment suggestions for uninitialized bindings try-job: i686-msvc-2
2 parents 9602bda + b994a05 commit 9e34c55

4 files changed

Lines changed: 122 additions & 8 deletions

File tree

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -914,32 +914,36 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
914914
if show_assign_sugg {
915915
struct LetVisitor {
916916
decl_span: Span,
917-
sugg_span: Option<Span>,
917+
sugg: Option<(Span, bool)>,
918918
}
919919

920920
impl<'v> Visitor<'v> for LetVisitor {
921921
fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) {
922-
if self.sugg_span.is_some() {
922+
if self.sugg.is_some() {
923923
return;
924924
}
925925

926926
// FIXME: We make sure that this is a normal top-level binding,
927927
// but we could suggest `todo!()` for all uninitialized bindings in the pattern
928928
if let hir::StmtKind::Let(hir::LetStmt { span, ty, init: None, pat, .. }) =
929929
&ex.kind
930-
&& let hir::PatKind::Binding(..) = pat.kind
930+
&& let hir::PatKind::Binding(binding_mode, ..) = pat.kind
931931
&& span.contains(self.decl_span)
932932
{
933-
self.sugg_span = ty.map_or(Some(self.decl_span), |ty| Some(ty.span));
933+
// Insert after the whole binding pattern so suggestions stay valid for
934+
// bindings with `@` subpatterns like `ref mut x @ v`.
935+
let strip_ref = matches!(binding_mode.0, hir::ByRef::Yes(..));
936+
self.sugg =
937+
ty.map_or(Some((pat.span, strip_ref)), |ty| Some((ty.span, strip_ref)));
934938
}
935939
hir::intravisit::walk_stmt(self, ex);
936940
}
937941
}
938942

939-
let mut visitor = LetVisitor { decl_span, sugg_span: None };
943+
let mut visitor = LetVisitor { decl_span, sugg: None };
940944
visitor.visit_body(&body);
941-
if let Some(span) = visitor.sugg_span {
942-
self.suggest_assign_value(&mut err, moved_place, span);
945+
if let Some((span, strip_ref)) = visitor.sugg {
946+
self.suggest_assign_value(&mut err, moved_place, span, strip_ref);
943947
}
944948
}
945949
err
@@ -950,8 +954,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
950954
err: &mut Diag<'_>,
951955
moved_place: PlaceRef<'tcx>,
952956
sugg_span: Span,
957+
strip_ref: bool,
953958
) {
954-
let ty = moved_place.ty(self.body, self.infcx.tcx).ty;
959+
let mut ty = moved_place.ty(self.body, self.infcx.tcx).ty;
960+
if strip_ref && let ty::Ref(_, inner, _) = ty.kind() {
961+
ty = *inner;
962+
}
955963
debug!("ty: {:?}, kind: {:?}", ty, ty.kind());
956964

957965
let Some(assign_value) = self.infcx.err_ctxt().ty_kind_suggestion(self.infcx.param_env, ty)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@ run-rustfix
2+
#![allow(unused_variables)]
3+
4+
fn main() {
5+
let ref mut x @ _v = 42;
6+
*x = 1; //~ ERROR used binding `x` isn't initialized
7+
8+
let a @ _b: i32 = 42;
9+
println!("{}", a); //~ ERROR used binding `a` isn't initialized
10+
11+
let ref c @ _d: i32 = 42;
12+
println!("{:?}", c); //~ ERROR used binding `c` isn't initialized
13+
14+
let ref e: i32 = 42;
15+
println!("{:?}", e); //~ ERROR used binding `e` isn't initialized
16+
17+
let ref mut y = 42;
18+
*y = 1; //~ ERROR used binding `y` isn't initialized
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@ run-rustfix
2+
#![allow(unused_variables)]
3+
4+
fn main() {
5+
let ref mut x @ _v;
6+
*x = 1; //~ ERROR used binding `x` isn't initialized
7+
8+
let a @ _b: i32;
9+
println!("{}", a); //~ ERROR used binding `a` isn't initialized
10+
11+
let ref c @ _d: i32;
12+
println!("{:?}", c); //~ ERROR used binding `c` isn't initialized
13+
14+
let ref e: i32;
15+
println!("{:?}", e); //~ ERROR used binding `e` isn't initialized
16+
17+
let ref mut y;
18+
*y = 1; //~ ERROR used binding `y` isn't initialized
19+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
error[E0381]: used binding `x` isn't initialized
2+
--> $DIR/assign-value-after-at-pattern-issue-145564.rs:6:5
3+
|
4+
LL | let ref mut x @ _v;
5+
| --------- binding declared here but left uninitialized
6+
LL | *x = 1;
7+
| ^^^^^^ `x` used here but it isn't initialized
8+
|
9+
help: consider assigning a value
10+
|
11+
LL | let ref mut x @ _v = 42;
12+
| ++++
13+
14+
error[E0381]: used binding `a` isn't initialized
15+
--> $DIR/assign-value-after-at-pattern-issue-145564.rs:9:20
16+
|
17+
LL | let a @ _b: i32;
18+
| - binding declared here but left uninitialized
19+
LL | println!("{}", a);
20+
| ^ `a` used here but it isn't initialized
21+
|
22+
help: consider assigning a value
23+
|
24+
LL | let a @ _b: i32 = 42;
25+
| ++++
26+
27+
error[E0381]: used binding `c` isn't initialized
28+
--> $DIR/assign-value-after-at-pattern-issue-145564.rs:12:22
29+
|
30+
LL | let ref c @ _d: i32;
31+
| ----- binding declared here but left uninitialized
32+
LL | println!("{:?}", c);
33+
| ^ `c` used here but it isn't initialized
34+
|
35+
help: consider assigning a value
36+
|
37+
LL | let ref c @ _d: i32 = 42;
38+
| ++++
39+
40+
error[E0381]: used binding `e` isn't initialized
41+
--> $DIR/assign-value-after-at-pattern-issue-145564.rs:15:22
42+
|
43+
LL | let ref e: i32;
44+
| ----- binding declared here but left uninitialized
45+
LL | println!("{:?}", e);
46+
| ^ `e` used here but it isn't initialized
47+
|
48+
help: consider assigning a value
49+
|
50+
LL | let ref e: i32 = 42;
51+
| ++++
52+
53+
error[E0381]: used binding `y` isn't initialized
54+
--> $DIR/assign-value-after-at-pattern-issue-145564.rs:18:5
55+
|
56+
LL | let ref mut y;
57+
| --------- binding declared here but left uninitialized
58+
LL | *y = 1;
59+
| ^^^^^^ `y` used here but it isn't initialized
60+
|
61+
help: consider assigning a value
62+
|
63+
LL | let ref mut y = 42;
64+
| ++++
65+
66+
error: aborting due to 5 previous errors
67+
68+
For more information about this error, try `rustc --explain E0381`.

0 commit comments

Comments
 (0)