Skip to content

Commit 6fe4cf7

Browse files
committed
Migrate mir_build's borrow conflicts
1 parent ae4d89d commit 6fe4cf7

11 files changed

+302
-273
lines changed

compiler/rustc_error_messages/locales/en-US/mir_build.ftl

+12-4
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,18 @@ mir_build_borrow_of_moved_value = borrow of moved value
299299
.suggestion = borrow this binding in the pattern to avoid moving the value
300300
301301
mir_build_multiple_mut_borrows = cannot borrow value as mutable more than once at a time
302-
.label = first mutable borrow, by `{$name}`, occurs here
303-
.mutable_borrow = another mutable borrow, by `{$name_mut}`, occurs here
304-
.immutable_borrow = also borrowed as immutable, by `{$name_immut}`, here
305-
.moved = also moved into `{$name_moved}` here
302+
303+
mir_build_already_borrowed = cannot borrow value as mutable because it is also borrowed as immutable
304+
305+
mir_build_already_mut_borrowed = cannot borrow value as immutable because it is also borrowed as mutable
306+
307+
mir_build_moved_while_borrowed = cannot move out of value because it is borrowed
308+
309+
mir_build_mutable_borrow = value is mutably borrowed by `{$name}` here
310+
311+
mir_build_borrow = value is borrowed by `{$name}` here
312+
313+
mir_build_moved = value is moved into `{$name}` here
306314
307315
mir_build_union_pattern = cannot use unions in constant patterns
308316

compiler/rustc_mir_build/src/errors.rs

+37-13
Original file line numberDiff line numberDiff line change
@@ -600,32 +600,56 @@ pub struct BorrowOfMovedValue<'tcx> {
600600
pub struct MultipleMutBorrows {
601601
#[primary_span]
602602
pub span: Span,
603-
#[label]
604-
pub binding_span: Span,
605603
#[subdiagnostic]
606-
pub occurences: Vec<MultipleMutBorrowOccurence>,
607-
pub name: Ident,
604+
pub occurences: Vec<Conflict>,
605+
}
606+
607+
#[derive(Diagnostic)]
608+
#[diag(mir_build_already_borrowed)]
609+
pub struct AlreadyBorrowed {
610+
#[primary_span]
611+
pub span: Span,
612+
#[subdiagnostic]
613+
pub occurences: Vec<Conflict>,
614+
}
615+
616+
#[derive(Diagnostic)]
617+
#[diag(mir_build_already_mut_borrowed)]
618+
pub struct AlreadyMutBorrowed {
619+
#[primary_span]
620+
pub span: Span,
621+
#[subdiagnostic]
622+
pub occurences: Vec<Conflict>,
623+
}
624+
625+
#[derive(Diagnostic)]
626+
#[diag(mir_build_moved_while_borrowed)]
627+
pub struct MovedWhileBorrowed {
628+
#[primary_span]
629+
pub span: Span,
630+
#[subdiagnostic]
631+
pub occurences: Vec<Conflict>,
608632
}
609633

610634
#[derive(Subdiagnostic)]
611-
pub enum MultipleMutBorrowOccurence {
612-
#[label(mutable_borrow)]
613-
Mutable {
635+
pub enum Conflict {
636+
#[label(mir_build_mutable_borrow)]
637+
Mut {
614638
#[primary_span]
615639
span: Span,
616-
name_mut: Ident,
640+
name: Ident,
617641
},
618-
#[label(immutable_borrow)]
619-
Immutable {
642+
#[label(mir_build_borrow)]
643+
Ref {
620644
#[primary_span]
621645
span: Span,
622-
name_immut: Ident,
646+
name: Ident,
623647
},
624-
#[label(moved)]
648+
#[label(mir_build_moved)]
625649
Moved {
626650
#[primary_span]
627651
span: Span,
628-
name_moved: Ident,
652+
name: Ident,
629653
},
630654
}
631655

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+37-40
Original file line numberDiff line numberDiff line change
@@ -914,58 +914,55 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
914914
sub.each_binding(|_, hir_id, span, name| {
915915
match typeck_results.extract_binding_mode(sess, hir_id, span) {
916916
Some(ty::BindByReference(mut_inner)) => match (mut_outer, mut_inner) {
917-
(Mutability::Not, Mutability::Not) => {} // Both sides are `ref`.
918-
(Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push((span, name)), // 2x `ref mut`.
919-
_ => conflicts_mut_ref.push((span, name)), // `ref` + `ref mut` in either direction.
917+
// Both sides are `ref`.
918+
(Mutability::Not, Mutability::Not) => {}
919+
// 2x `ref mut`.
920+
(Mutability::Mut, Mutability::Mut) => {
921+
conflicts_mut_mut.push(Conflict::Mut { span, name })
922+
}
923+
(Mutability::Not, Mutability::Mut) => {
924+
conflicts_mut_ref.push(Conflict::Mut { span, name })
925+
}
926+
(Mutability::Mut, Mutability::Not) => {
927+
conflicts_mut_ref.push(Conflict::Ref { span, name })
928+
}
920929
},
921930
Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id) => {
922-
conflicts_move.push((span, name)) // `ref mut?` + by-move conflict.
931+
conflicts_move.push(Conflict::Moved { span, name }) // `ref mut?` + by-move conflict.
923932
}
924933
Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine.
925934
}
926935
});
927936

937+
let report_mut_mut = !conflicts_mut_mut.is_empty();
938+
let report_mut_ref = !conflicts_mut_ref.is_empty();
939+
let report_move_conflict = !conflicts_move.is_empty();
940+
941+
let mut occurences = match mut_outer {
942+
Mutability::Mut => vec![Conflict::Mut { span: binding_span, name }],
943+
Mutability::Not => vec![Conflict::Ref { span: binding_span, name }],
944+
};
945+
occurences.extend(conflicts_mut_mut);
946+
occurences.extend(conflicts_mut_ref);
947+
occurences.extend(conflicts_move);
948+
928949
// Report errors if any.
929-
if !conflicts_mut_mut.is_empty() {
950+
if report_mut_mut {
930951
// Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`.
931-
let mut occurences = vec![];
932-
933-
for (span, name_mut) in conflicts_mut_mut {
934-
occurences.push(MultipleMutBorrowOccurence::Mutable { span, name_mut });
935-
}
936-
for (span, name_immut) in conflicts_mut_ref {
937-
occurences.push(MultipleMutBorrowOccurence::Immutable { span, name_immut });
938-
}
939-
for (span, name_moved) in conflicts_move {
940-
occurences.push(MultipleMutBorrowOccurence::Moved { span, name_moved });
941-
}
942-
sess.emit_err(MultipleMutBorrows { span: pat.span, binding_span, occurences, name });
943-
} else if !conflicts_mut_ref.is_empty() {
952+
sess.emit_err(MultipleMutBorrows { span: pat.span, occurences });
953+
} else if report_mut_ref {
944954
// Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse.
945-
let (primary, also) = match mut_outer {
946-
Mutability::Mut => ("mutable", "immutable"),
947-
Mutability::Not => ("immutable", "mutable"),
955+
match mut_outer {
956+
Mutability::Mut => {
957+
sess.emit_err(AlreadyMutBorrowed { span: pat.span, occurences });
958+
}
959+
Mutability::Not => {
960+
sess.emit_err(AlreadyBorrowed { span: pat.span, occurences });
961+
}
948962
};
949-
let msg =
950-
format!("cannot borrow value as {} because it is also borrowed as {}", also, primary);
951-
let mut err = sess.struct_span_err(pat.span, &msg);
952-
err.span_label(binding_span, format!("{} borrow, by `{}`, occurs here", primary, name));
953-
for (span, name) in conflicts_mut_ref {
954-
err.span_label(span, format!("{} borrow, by `{}`, occurs here", also, name));
955-
}
956-
for (span, name) in conflicts_move {
957-
err.span_label(span, format!("also moved into `{}` here", name));
958-
}
959-
err.emit();
960-
} else if !conflicts_move.is_empty() {
963+
} else if report_move_conflict {
961964
// Report by-ref and by-move conflicts, e.g. `ref x @ y`.
962-
let mut err =
963-
sess.struct_span_err(pat.span, "cannot move out of value because it is borrowed");
964-
err.span_label(binding_span, format!("value borrowed, by `{}`, here", name));
965-
for (span, name) in conflicts_move {
966-
err.span_label(span, format!("value moved into `{}` here", name));
967-
}
968-
err.emit();
965+
sess.emit_err(MovedWhileBorrowed { span: pat.span, occurences });
969966
}
970967
}
971968

tests/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
44
LL | ref foo @ [.., ref mut bar] => (),
55
| -------^^^^^^^^-----------^
66
| | |
7-
| | mutable borrow, by `bar`, occurs here
8-
| immutable borrow, by `foo`, occurs here
7+
| | value is mutably borrowed by `bar` here
8+
| value is borrowed by `foo` here
99

1010
error: cannot borrow value as mutable because it is also borrowed as immutable
1111
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:120:9
1212
|
1313
LL | ref foo @ Some(box ref mut s) => (),
1414
| -------^^^^^^^^^^^^---------^
1515
| | |
16-
| | mutable borrow, by `s`, occurs here
17-
| immutable borrow, by `foo`, occurs here
16+
| | value is mutably borrowed by `s` here
17+
| value is borrowed by `foo` here
1818

1919
error[E0382]: borrow of moved value: `x`
2020
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:18:5

tests/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ error: cannot move out of value because it is borrowed
44
LL | Some(ref _y @ _z) => {}
55
| ------^^^--
66
| | |
7-
| | value moved into `_z` here
8-
| value borrowed, by `_y`, here
7+
| | value is moved into `_z` here
8+
| value is borrowed by `_y` here
99

1010
error: borrow of moved value
1111
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:19:14
@@ -28,8 +28,8 @@ error: cannot move out of value because it is borrowed
2828
LL | Some(ref mut _y @ _z) => {}
2929
| ----------^^^--
3030
| | |
31-
| | value moved into `_z` here
32-
| value borrowed, by `_y`, here
31+
| | value is moved into `_z` here
32+
| value is mutably borrowed by `_y` here
3333

3434
error: borrow of moved value
3535
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:33:14

tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr

+16-16
Original file line numberDiff line numberDiff line change
@@ -4,71 +4,71 @@ error: cannot move out of value because it is borrowed
44
LL | let ref a @ box b = Box::new(NC);
55
| -----^^^^^^^-
66
| | |
7-
| | value moved into `b` here
8-
| value borrowed, by `a`, here
7+
| | value is moved into `b` here
8+
| value is borrowed by `a` here
99

1010
error: cannot borrow value as mutable because it is also borrowed as immutable
1111
--> $DIR/borrowck-pat-at-and-box.rs:34:9
1212
|
1313
LL | let ref a @ box ref mut b = Box::new(nc());
1414
| -----^^^^^^^---------
1515
| | |
16-
| | mutable borrow, by `b`, occurs here
17-
| immutable borrow, by `a`, occurs here
16+
| | value is mutably borrowed by `b` here
17+
| value is borrowed by `a` here
1818

1919
error: cannot borrow value as mutable because it is also borrowed as immutable
2020
--> $DIR/borrowck-pat-at-and-box.rs:36:9
2121
|
2222
LL | let ref a @ box ref mut b = Box::new(NC);
2323
| -----^^^^^^^---------
2424
| | |
25-
| | mutable borrow, by `b`, occurs here
26-
| immutable borrow, by `a`, occurs here
25+
| | value is mutably borrowed by `b` here
26+
| value is borrowed by `a` here
2727

2828
error: cannot borrow value as mutable because it is also borrowed as immutable
2929
--> $DIR/borrowck-pat-at-and-box.rs:38:9
3030
|
3131
LL | let ref a @ box ref mut b = Box::new(NC);
3232
| -----^^^^^^^---------
3333
| | |
34-
| | mutable borrow, by `b`, occurs here
35-
| immutable borrow, by `a`, occurs here
34+
| | value is mutably borrowed by `b` here
35+
| value is borrowed by `a` here
3636

3737
error: cannot borrow value as mutable because it is also borrowed as immutable
3838
--> $DIR/borrowck-pat-at-and-box.rs:42:9
3939
|
4040
LL | let ref a @ box ref mut b = Box::new(NC);
4141
| -----^^^^^^^---------
4242
| | |
43-
| | mutable borrow, by `b`, occurs here
44-
| immutable borrow, by `a`, occurs here
43+
| | value is mutably borrowed by `b` here
44+
| value is borrowed by `a` here
4545

4646
error: cannot borrow value as immutable because it is also borrowed as mutable
4747
--> $DIR/borrowck-pat-at-and-box.rs:48:9
4848
|
4949
LL | let ref mut a @ box ref b = Box::new(NC);
5050
| ---------^^^^^^^-----
5151
| | |
52-
| | immutable borrow, by `b`, occurs here
53-
| mutable borrow, by `a`, occurs here
52+
| | value is borrowed by `b` here
53+
| value is mutably borrowed by `a` here
5454

5555
error: cannot borrow value as immutable because it is also borrowed as mutable
5656
--> $DIR/borrowck-pat-at-and-box.rs:62:9
5757
|
5858
LL | ref mut a @ box ref b => {
5959
| ---------^^^^^^^-----
6060
| | |
61-
| | immutable borrow, by `b`, occurs here
62-
| mutable borrow, by `a`, occurs here
61+
| | value is borrowed by `b` here
62+
| value is mutably borrowed by `a` here
6363

6464
error: cannot borrow value as immutable because it is also borrowed as mutable
6565
--> $DIR/borrowck-pat-at-and-box.rs:54:11
6666
|
6767
LL | fn f5(ref mut a @ box ref b: Box<NC>) {
6868
| ---------^^^^^^^-----
6969
| | |
70-
| | immutable borrow, by `b`, occurs here
71-
| mutable borrow, by `a`, occurs here
70+
| | value is borrowed by `b` here
71+
| value is mutably borrowed by `a` here
7272

7373
error[E0382]: borrow of moved value
7474
--> $DIR/borrowck-pat-at-and-box.rs:31:9

0 commit comments

Comments
 (0)