Auto merge of #107328 - matthiaskrgr:rollup-lfqwo0o, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #106904 (Preserve split DWARF files when building archives.) - #106971 (Handle diagnostics customization on the fluent side (for one specific diagnostic)) - #106978 (Migrate mir_build's borrow conflicts) - #107150 (`ty::tls` cleanups) - #107168 (Use a type-alias-impl-trait in `ObligationForest`) - #107189 (Encode info for Adt in a single place.) - #107322 (Custom mir: Add support for some remaining, easy to support constructs) - #107323 (Disable ConstGoto opt in cleanup blocks) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
c62665e09c
36 changed files with 641 additions and 611 deletions
|
@ -18,6 +18,9 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
|||
@call("mir_storage_dead", args) => {
|
||||
Ok(StatementKind::StorageDead(self.parse_local(args[0])?))
|
||||
},
|
||||
@call("mir_deinit", args) => {
|
||||
Ok(StatementKind::Deinit(Box::new(self.parse_place(args[0])?)))
|
||||
},
|
||||
@call("mir_retag", args) => {
|
||||
Ok(StatementKind::Retag(RetagKind::Default, Box::new(self.parse_place(args[0])?)))
|
||||
},
|
||||
|
@ -141,6 +144,14 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
|||
fn parse_rvalue(&self, expr_id: ExprId) -> PResult<Rvalue<'tcx>> {
|
||||
parse_by_kind!(self, expr_id, _, "rvalue",
|
||||
@call("mir_discriminant", args) => self.parse_place(args[0]).map(Rvalue::Discriminant),
|
||||
@call("mir_checked", args) => {
|
||||
parse_by_kind!(self, args[0], _, "binary op",
|
||||
ExprKind::Binary { op, lhs, rhs } => Ok(Rvalue::CheckedBinaryOp(
|
||||
*op, Box::new((self.parse_operand(*lhs)?, self.parse_operand(*rhs)?))
|
||||
)),
|
||||
)
|
||||
},
|
||||
@call("mir_len", args) => Ok(Rvalue::Len(self.parse_place(args[0])?)),
|
||||
ExprKind::Borrow { borrow_kind, arg } => Ok(
|
||||
Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
|
||||
),
|
||||
|
@ -153,6 +164,9 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
|||
ExprKind::Unary { op, arg } => Ok(
|
||||
Rvalue::UnaryOp(*op, self.parse_operand(*arg)?)
|
||||
),
|
||||
ExprKind::Repeat { value, count } => Ok(
|
||||
Rvalue::Repeat(self.parse_operand(*value)?, *count)
|
||||
),
|
||||
_ => self.parse_operand(expr_id).map(Rvalue::Use),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -600,32 +600,56 @@ pub struct BorrowOfMovedValue<'tcx> {
|
|||
pub struct MultipleMutBorrows {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[label]
|
||||
pub binding_span: Span,
|
||||
#[subdiagnostic]
|
||||
pub occurences: Vec<MultipleMutBorrowOccurence>,
|
||||
pub name: Ident,
|
||||
pub occurences: Vec<Conflict>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_build_already_borrowed)]
|
||||
pub struct AlreadyBorrowed {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub occurences: Vec<Conflict>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_build_already_mut_borrowed)]
|
||||
pub struct AlreadyMutBorrowed {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub occurences: Vec<Conflict>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_build_moved_while_borrowed)]
|
||||
pub struct MovedWhileBorrowed {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub occurences: Vec<Conflict>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum MultipleMutBorrowOccurence {
|
||||
#[label(mutable_borrow)]
|
||||
Mutable {
|
||||
pub enum Conflict {
|
||||
#[label(mir_build_mutable_borrow)]
|
||||
Mut {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
name_mut: Ident,
|
||||
name: Ident,
|
||||
},
|
||||
#[label(immutable_borrow)]
|
||||
Immutable {
|
||||
#[label(mir_build_borrow)]
|
||||
Ref {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
name_immut: Ident,
|
||||
name: Ident,
|
||||
},
|
||||
#[label(moved)]
|
||||
#[label(mir_build_moved)]
|
||||
Moved {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
name_moved: Ident,
|
||||
name: Ident,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -926,58 +926,55 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
|
|||
sub.each_binding(|_, hir_id, span, name| {
|
||||
match typeck_results.extract_binding_mode(sess, hir_id, span) {
|
||||
Some(ty::BindByReference(mut_inner)) => match (mut_outer, mut_inner) {
|
||||
(Mutability::Not, Mutability::Not) => {} // Both sides are `ref`.
|
||||
(Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push((span, name)), // 2x `ref mut`.
|
||||
_ => conflicts_mut_ref.push((span, name)), // `ref` + `ref mut` in either direction.
|
||||
// Both sides are `ref`.
|
||||
(Mutability::Not, Mutability::Not) => {}
|
||||
// 2x `ref mut`.
|
||||
(Mutability::Mut, Mutability::Mut) => {
|
||||
conflicts_mut_mut.push(Conflict::Mut { span, name })
|
||||
}
|
||||
(Mutability::Not, Mutability::Mut) => {
|
||||
conflicts_mut_ref.push(Conflict::Mut { span, name })
|
||||
}
|
||||
(Mutability::Mut, Mutability::Not) => {
|
||||
conflicts_mut_ref.push(Conflict::Ref { span, name })
|
||||
}
|
||||
},
|
||||
Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id) => {
|
||||
conflicts_move.push((span, name)) // `ref mut?` + by-move conflict.
|
||||
conflicts_move.push(Conflict::Moved { span, name }) // `ref mut?` + by-move conflict.
|
||||
}
|
||||
Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine.
|
||||
}
|
||||
});
|
||||
|
||||
// Report errors if any.
|
||||
if !conflicts_mut_mut.is_empty() {
|
||||
// Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`.
|
||||
let mut occurences = vec![];
|
||||
let report_mut_mut = !conflicts_mut_mut.is_empty();
|
||||
let report_mut_ref = !conflicts_mut_ref.is_empty();
|
||||
let report_move_conflict = !conflicts_move.is_empty();
|
||||
|
||||
for (span, name_mut) in conflicts_mut_mut {
|
||||
occurences.push(MultipleMutBorrowOccurence::Mutable { span, name_mut });
|
||||
}
|
||||
for (span, name_immut) in conflicts_mut_ref {
|
||||
occurences.push(MultipleMutBorrowOccurence::Immutable { span, name_immut });
|
||||
}
|
||||
for (span, name_moved) in conflicts_move {
|
||||
occurences.push(MultipleMutBorrowOccurence::Moved { span, name_moved });
|
||||
}
|
||||
sess.emit_err(MultipleMutBorrows { span: pat.span, binding_span, occurences, name });
|
||||
} else if !conflicts_mut_ref.is_empty() {
|
||||
let mut occurences = match mut_outer {
|
||||
Mutability::Mut => vec![Conflict::Mut { span: binding_span, name }],
|
||||
Mutability::Not => vec![Conflict::Ref { span: binding_span, name }],
|
||||
};
|
||||
occurences.extend(conflicts_mut_mut);
|
||||
occurences.extend(conflicts_mut_ref);
|
||||
occurences.extend(conflicts_move);
|
||||
|
||||
// Report errors if any.
|
||||
if report_mut_mut {
|
||||
// Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`.
|
||||
sess.emit_err(MultipleMutBorrows { span: pat.span, occurences });
|
||||
} else if report_mut_ref {
|
||||
// Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse.
|
||||
let (primary, also) = match mut_outer {
|
||||
Mutability::Mut => ("mutable", "immutable"),
|
||||
Mutability::Not => ("immutable", "mutable"),
|
||||
match mut_outer {
|
||||
Mutability::Mut => {
|
||||
sess.emit_err(AlreadyMutBorrowed { span: pat.span, occurences });
|
||||
}
|
||||
Mutability::Not => {
|
||||
sess.emit_err(AlreadyBorrowed { span: pat.span, occurences });
|
||||
}
|
||||
};
|
||||
let msg =
|
||||
format!("cannot borrow value as {} because it is also borrowed as {}", also, primary);
|
||||
let mut err = sess.struct_span_err(pat.span, &msg);
|
||||
err.span_label(binding_span, format!("{} borrow, by `{}`, occurs here", primary, name));
|
||||
for (span, name) in conflicts_mut_ref {
|
||||
err.span_label(span, format!("{} borrow, by `{}`, occurs here", also, name));
|
||||
}
|
||||
for (span, name) in conflicts_move {
|
||||
err.span_label(span, format!("also moved into `{}` here", name));
|
||||
}
|
||||
err.emit();
|
||||
} else if !conflicts_move.is_empty() {
|
||||
} else if report_move_conflict {
|
||||
// Report by-ref and by-move conflicts, e.g. `ref x @ y`.
|
||||
let mut err =
|
||||
sess.struct_span_err(pat.span, "cannot move out of value because it is borrowed");
|
||||
err.span_label(binding_span, format!("value borrowed, by `{}`, here", name));
|
||||
for (span, name) in conflicts_move {
|
||||
err.span_label(span, format!("value moved into `{}` here", name));
|
||||
}
|
||||
err.emit();
|
||||
sess.emit_err(MovedWhileBorrowed { span: pat.span, occurences });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue