1
Fork 0

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:
bors 2023-01-26 15:58:08 +00:00
commit c62665e09c
36 changed files with 641 additions and 611 deletions

View file

@ -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),
)
}

View file

@ -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,
},
}

View file

@ -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 });
}
}