Skip to content

Commit e898da1

Browse files
author
The Miri Cronjob Bot
committed
Merge from rustc
2 parents 332fefb + 5079acc commit e898da1

File tree

495 files changed

+5337
-1957
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

495 files changed

+5337
-1957
lines changed

Cargo.lock

Lines changed: 74 additions & 60 deletions
Large diffs are not rendered by default.

compiler/rustc_ast_pretty/src/pprust/state/expr.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,9 @@ impl<'a> State<'a> {
213213

214214
fn print_expr_call(&mut self, func: &ast::Expr, args: &[P<ast::Expr>], fixup: FixupContext) {
215215
let needs_paren = match func.kind {
216-
ast::ExprKind::Field(..) => true,
216+
// In order to call a named field, needs parens: `(self.fun)()`
217+
// But not for an unnamed field: `self.0()`
218+
ast::ExprKind::Field(_, name) => !name.is_numeric(),
217219
_ => func.precedence() < ExprPrecedence::Unambiguous,
218220
};
219221

@@ -245,19 +247,21 @@ impl<'a> State<'a> {
245247
base_args: &[P<ast::Expr>],
246248
fixup: FixupContext,
247249
) {
248-
// Unlike in `print_expr_call`, no change to fixup here because
250+
// The fixup here is different than in `print_expr_call` because
249251
// statement boundaries never occur in front of a `.` (or `?`) token.
250252
//
251-
// match () { _ => f }.method();
253+
// Needs parens:
254+
//
255+
// (loop { break x; })();
256+
//
257+
// Does not need parens:
258+
//
259+
// loop { break x; }.method();
252260
//
253-
// Parenthesizing only for precedence and not with regard to statement
254-
// boundaries, `$receiver.method()` can be parsed back as a statement
255-
// containing an expression if and only if `$receiver` can be parsed as
256-
// a statement containing an expression.
257261
self.print_expr_cond_paren(
258262
receiver,
259263
receiver.precedence() < ExprPrecedence::Unambiguous,
260-
fixup,
264+
fixup.leftmost_subexpression_with_dot(),
261265
);
262266

263267
self.word(".");
@@ -503,7 +507,7 @@ impl<'a> State<'a> {
503507
self.print_expr_cond_paren(
504508
expr,
505509
expr.precedence() < ExprPrecedence::Unambiguous,
506-
fixup,
510+
fixup.leftmost_subexpression_with_dot(),
507511
);
508512
self.word_nbsp(".match");
509513
}
@@ -567,7 +571,7 @@ impl<'a> State<'a> {
567571
self.print_expr_cond_paren(
568572
expr,
569573
expr.precedence() < ExprPrecedence::Unambiguous,
570-
fixup,
574+
fixup.leftmost_subexpression_with_dot(),
571575
);
572576
self.word(".await");
573577
}
@@ -606,7 +610,7 @@ impl<'a> State<'a> {
606610
self.print_expr_cond_paren(
607611
expr,
608612
expr.precedence() < ExprPrecedence::Unambiguous,
609-
fixup,
613+
fixup.leftmost_subexpression_with_dot(),
610614
);
611615
self.word(".");
612616
self.print_ident(*ident);
@@ -763,7 +767,11 @@ impl<'a> State<'a> {
763767
}
764768
}
765769
ast::ExprKind::Try(e) => {
766-
self.print_expr_cond_paren(e, e.precedence() < ExprPrecedence::Unambiguous, fixup);
770+
self.print_expr_cond_paren(
771+
e,
772+
e.precedence() < ExprPrecedence::Unambiguous,
773+
fixup.leftmost_subexpression_with_dot(),
774+
);
767775
self.word("?")
768776
}
769777
ast::ExprKind::TryBlock(blk) => {

compiler/rustc_ast_pretty/src/pprust/state/fixup.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,20 @@ impl FixupContext {
138138
}
139139
}
140140

141+
/// Transform this fixup into the one that should apply when printing a
142+
/// leftmost subexpression followed by a `.` or `?` token, which confer
143+
/// different statement boundary rules compared to other leftmost
144+
/// subexpressions.
145+
pub(crate) fn leftmost_subexpression_with_dot(self) -> Self {
146+
FixupContext {
147+
stmt: self.stmt || self.leftmost_subexpression_in_stmt,
148+
leftmost_subexpression_in_stmt: false,
149+
match_arm: self.match_arm || self.leftmost_subexpression_in_match_arm,
150+
leftmost_subexpression_in_match_arm: false,
151+
..self
152+
}
153+
}
154+
141155
/// Transform this fixup into the one that should apply when printing any
142156
/// subexpression that is neither a leftmost subexpression nor surrounded in
143157
/// delimiters.

compiler/rustc_borrowck/src/consumers.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ use rustc_middle::ty::TyCtxt;
88
pub use super::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation};
99
pub use super::constraints::OutlivesConstraint;
1010
pub use super::dataflow::{BorrowIndex, Borrows, calculate_borrows_out_of_scope_at_location};
11-
pub use super::facts::{AllFacts as PoloniusInput, PoloniusRegionVid, RustcFacts};
12-
pub use super::location::{LocationTable, RichLocation};
13-
pub use super::nll::PoloniusOutput;
1411
pub use super::place_ext::PlaceExt;
1512
pub use super::places_conflict::{PlaceConflictBias, places_conflict};
13+
pub use super::polonius::legacy::{
14+
AllFacts as PoloniusInput, LocationTable, PoloniusOutput, PoloniusRegionVid, RichLocation,
15+
RustcFacts,
16+
};
1617
pub use super::region_infer::RegionInferenceContext;
1718

1819
/// Options determining the output behavior of [`get_body_with_borrowck_facts`].

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
//! Borrow checker diagnostics.
22
3+
use std::collections::BTreeMap;
4+
35
use rustc_abi::{FieldIdx, VariantIdx};
6+
use rustc_data_structures::fx::FxIndexMap;
47
use rustc_errors::{Applicability, Diag, MultiSpan};
58
use rustc_hir::def::{CtorKind, Namespace};
69
use rustc_hir::{self as hir, CoroutineKind, LangItem};
@@ -17,10 +20,10 @@ use rustc_middle::mir::{
1720
use rustc_middle::ty::print::Print;
1821
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
1922
use rustc_middle::util::{CallDesugaringKind, call_kind};
20-
use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult};
23+
use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveOutIndex};
2124
use rustc_span::def_id::LocalDefId;
2225
use rustc_span::source_map::Spanned;
23-
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
26+
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
2427
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
2528
use rustc_trait_selection::infer::InferCtxtExt;
2629
use rustc_trait_selection::traits::{
@@ -68,6 +71,126 @@ pub(super) struct DescribePlaceOpt {
6871

6972
pub(super) struct IncludingTupleField(pub(super) bool);
7073

74+
enum BufferedDiag<'infcx> {
75+
Error(Diag<'infcx>),
76+
NonError(Diag<'infcx, ()>),
77+
}
78+
79+
impl<'infcx> BufferedDiag<'infcx> {
80+
fn sort_span(&self) -> Span {
81+
match self {
82+
BufferedDiag::Error(diag) => diag.sort_span,
83+
BufferedDiag::NonError(diag) => diag.sort_span,
84+
}
85+
}
86+
}
87+
88+
#[derive(Default)]
89+
pub(crate) struct BorrowckDiagnosticsBuffer<'infcx, 'tcx> {
90+
/// This field keeps track of move errors that are to be reported for given move indices.
91+
///
92+
/// There are situations where many errors can be reported for a single move out (see
93+
/// #53807) and we want only the best of those errors.
94+
///
95+
/// The `report_use_of_moved_or_uninitialized` function checks this map and replaces the
96+
/// diagnostic (if there is one) if the `Place` of the error being reported is a prefix of
97+
/// the `Place` of the previous most diagnostic. This happens instead of buffering the
98+
/// error. Once all move errors have been reported, any diagnostics in this map are added
99+
/// to the buffer to be emitted.
100+
///
101+
/// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary
102+
/// when errors in the map are being re-added to the error buffer so that errors with the
103+
/// same primary span come out in a consistent order.
104+
buffered_move_errors: BTreeMap<Vec<MoveOutIndex>, (PlaceRef<'tcx>, Diag<'infcx>)>,
105+
106+
buffered_mut_errors: FxIndexMap<Span, (Diag<'infcx>, usize)>,
107+
108+
/// Buffer of diagnostics to be reported. A mixture of error and non-error diagnostics.
109+
buffered_diags: Vec<BufferedDiag<'infcx>>,
110+
}
111+
112+
impl<'infcx, 'tcx> BorrowckDiagnosticsBuffer<'infcx, 'tcx> {
113+
pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
114+
self.buffered_diags.push(BufferedDiag::NonError(diag));
115+
}
116+
}
117+
118+
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
119+
pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) {
120+
self.diags_buffer.buffered_diags.push(BufferedDiag::Error(diag));
121+
}
122+
123+
pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
124+
self.diags_buffer.buffer_non_error(diag);
125+
}
126+
127+
pub(crate) fn buffer_move_error(
128+
&mut self,
129+
move_out_indices: Vec<MoveOutIndex>,
130+
place_and_err: (PlaceRef<'tcx>, Diag<'infcx>),
131+
) -> bool {
132+
if let Some((_, diag)) =
133+
self.diags_buffer.buffered_move_errors.insert(move_out_indices, place_and_err)
134+
{
135+
// Cancel the old diagnostic so we don't ICE
136+
diag.cancel();
137+
false
138+
} else {
139+
true
140+
}
141+
}
142+
143+
pub(crate) fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'infcx>, usize)> {
144+
// FIXME(#120456) - is `swap_remove` correct?
145+
self.diags_buffer.buffered_mut_errors.swap_remove(&span)
146+
}
147+
148+
pub(crate) fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) {
149+
self.diags_buffer.buffered_mut_errors.insert(span, (diag, count));
150+
}
151+
152+
pub(crate) fn emit_errors(&mut self) -> Option<ErrorGuaranteed> {
153+
let mut res = self.infcx.tainted_by_errors();
154+
155+
// Buffer any move errors that we collected and de-duplicated.
156+
for (_, (_, diag)) in std::mem::take(&mut self.diags_buffer.buffered_move_errors) {
157+
// We have already set tainted for this error, so just buffer it.
158+
self.buffer_error(diag);
159+
}
160+
for (_, (mut diag, count)) in std::mem::take(&mut self.diags_buffer.buffered_mut_errors) {
161+
if count > 10 {
162+
#[allow(rustc::diagnostic_outside_of_impl)]
163+
#[allow(rustc::untranslatable_diagnostic)]
164+
diag.note(format!("...and {} other attempted mutable borrows", count - 10));
165+
}
166+
self.buffer_error(diag);
167+
}
168+
169+
if !self.diags_buffer.buffered_diags.is_empty() {
170+
self.diags_buffer.buffered_diags.sort_by_key(|buffered_diag| buffered_diag.sort_span());
171+
for buffered_diag in self.diags_buffer.buffered_diags.drain(..) {
172+
match buffered_diag {
173+
BufferedDiag::Error(diag) => res = Some(diag.emit()),
174+
BufferedDiag::NonError(diag) => diag.emit(),
175+
}
176+
}
177+
}
178+
179+
res
180+
}
181+
182+
pub(crate) fn has_buffered_diags(&self) -> bool {
183+
self.diags_buffer.buffered_diags.is_empty()
184+
}
185+
186+
pub(crate) fn has_move_error(
187+
&self,
188+
move_out_indices: &[MoveOutIndex],
189+
) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> {
190+
self.diags_buffer.buffered_move_errors.get(move_out_indices)
191+
}
192+
}
193+
71194
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
72195
/// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure
73196
/// is moved after being invoked.

compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
3131
diag: &mut Diag<'_>,
3232
) {
3333
// We look at all the locals. Why locals? Because it's the best thing
34-
// I could think of that's correlated with the *instantiated* higer-ranked
34+
// I could think of that's correlated with the *instantiated* higher-ranked
3535
// binder for calls, since we don't really store those anywhere else.
3636
for ty in self.body.local_decls.iter().map(|local| local.ty) {
3737
if !ty.has_opaque_types() {

0 commit comments

Comments
 (0)