Skip to content

Commit 417e0fd

Browse files
Rollup merge of rust-lang#158360 - oli-obk:borrowck-cleanups, r=lcnr
Various borrowck cleanups and param_env/opaque_types_defined_by query simplifications for typeck children Various things I noticed while figuring out how to best allow changing some borrowck errors into FCWs cc @rust-lang/types for the typeck children stuff, in case I missed some memo and am undoing some work r? @ghost need perf first
2 parents 40557f6 + 7ccc34f commit 417e0fd

16 files changed

Lines changed: 124 additions & 120 deletions

File tree

compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
706706
Some(Cause::LiveVar(..) | Cause::DropVar(..)) | None => {
707707
// Here, under NLL: no cause was found. Under polonius: no cause was found, or a
708708
// boring local was found, which we ignore like NLLs do to match its diagnostics.
709-
if let Some(region) = self.to_error_region_vid(borrow_region_vid) {
709+
if let Some(region) = self.regioncx.to_error_region_vid(borrow_region_vid) {
710710
let (category, from_closure, span, region_name, path) =
711711
self.free_region_constraint_info(borrow_region_vid, region);
712712
if let Some(region_name) = region_name {

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,42 @@ impl<'infcx, 'tcx> BorrowckDiagnosticsBuffer<'infcx, 'tcx> {
116116
pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
117117
self.buffered_diags.push(BufferedDiag::NonError(diag));
118118
}
119+
pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) {
120+
self.buffered_diags.push(BufferedDiag::Error(diag));
121+
}
122+
123+
pub(crate) fn emit_errors(&mut self) -> Option<ErrorGuaranteed> {
124+
let mut res = None;
125+
126+
// Buffer any move errors that we collected and de-duplicated.
127+
for (_, (_, diag)) in std::mem::take(&mut self.buffered_move_errors) {
128+
// We have already set tainted for this error, so just buffer it.
129+
self.buffer_error(diag);
130+
}
131+
for (_, (mut diag, count)) in std::mem::take(&mut self.buffered_mut_errors) {
132+
if count > 10 {
133+
diag.note(format!("...and {} other attempted mutable borrows", count - 10));
134+
}
135+
self.buffer_error(diag);
136+
}
137+
138+
if !self.buffered_diags.is_empty() {
139+
self.buffered_diags.sort_by_key(|buffered_diag| buffered_diag.sort_span());
140+
for buffered_diag in self.buffered_diags.drain(..) {
141+
match buffered_diag {
142+
BufferedDiag::Error(diag) => res = Some(diag.emit()),
143+
BufferedDiag::NonError(diag) => diag.emit(),
144+
}
145+
}
146+
}
147+
148+
res
149+
}
119150
}
120151

121152
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
122153
pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) {
123-
self.diags_buffer.buffered_diags.push(BufferedDiag::Error(diag));
154+
self.diags_buffer.buffer_error(diag);
124155
}
125156

126157
pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
@@ -152,34 +183,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
152183
self.diags_buffer.buffered_mut_errors.insert(span, (diag, count));
153184
}
154185

155-
pub(crate) fn emit_errors(&mut self) -> Option<ErrorGuaranteed> {
156-
let mut res = self.infcx.tainted_by_errors();
157-
158-
// Buffer any move errors that we collected and de-duplicated.
159-
for (_, (_, diag)) in std::mem::take(&mut self.diags_buffer.buffered_move_errors) {
160-
// We have already set tainted for this error, so just buffer it.
161-
self.buffer_error(diag);
162-
}
163-
for (_, (mut diag, count)) in std::mem::take(&mut self.diags_buffer.buffered_mut_errors) {
164-
if count > 10 {
165-
diag.note(format!("...and {} other attempted mutable borrows", count - 10));
166-
}
167-
self.buffer_error(diag);
168-
}
169-
170-
if !self.diags_buffer.buffered_diags.is_empty() {
171-
self.diags_buffer.buffered_diags.sort_by_key(|buffered_diag| buffered_diag.sort_span());
172-
for buffered_diag in self.diags_buffer.buffered_diags.drain(..) {
173-
match buffered_diag {
174-
BufferedDiag::Error(diag) => res = Some(diag.emit()),
175-
BufferedDiag::NonError(diag) => diag.emit(),
176-
}
177-
}
178-
}
179-
180-
res
181-
}
182-
183186
pub(crate) fn has_buffered_diags(&self) -> bool {
184187
self.diags_buffer.buffered_diags.is_empty()
185188
}

compiler/rustc_borrowck/src/diagnostics/opaque_types.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
2828
}
2929

3030
let infcx = self.infcx;
31-
let mut guar = None;
3231
let mut last_unexpected_hidden_region: Option<(Span, Ty<'_>, ty::OpaqueTypeKey<'tcx>)> =
3332
None;
3433
for error in errors {
35-
guar = Some(match error {
34+
match error {
3635
DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err) => err.report(infcx),
3736
DeferredOpaqueTypeError::LifetimeMismatchOpaqueParam(err) => {
3837
infcx.dcx().emit_err(err)
@@ -82,11 +81,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
8281
)
8382
),
8483
),
85-
});
84+
};
8685
}
87-
let guar = guar.unwrap();
88-
self.root_cx.set_tainted_by_errors(guar);
89-
self.infcx.set_tainted_by_errors(guar);
9086
}
9187

9288
/// Try to note when an opaque is involved in a borrowck error and that

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use rustc_trait_selection::traits::{Obligation, ObligationCtxt};
2828
use tracing::{debug, instrument, trace};
2929

3030
use super::{LIMITATION_NOTE, OutlivesSuggestionBuilder, RegionName, RegionNameSource};
31+
use crate::consumers::RegionInferenceContext;
3132
use crate::nll::ConstraintDescription;
3233
use crate::region_infer::{BlameConstraint, TypeTest};
3334
use crate::session_diagnostics::{
@@ -134,28 +135,28 @@ pub(crate) struct ErrorConstraintInfo<'tcx> {
134135
pub(super) span: Span,
135136
}
136137

137-
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
138+
impl<'tcx> RegionInferenceContext<'tcx> {
138139
/// Converts a region inference variable into a `ty::Region` that
139140
/// we can use for error reporting. If `r` is universally bound,
140141
/// then we use the name that we have on record for it. If `r` is
141142
/// existentially bound, then we check its inferred value and try
142143
/// to find a good name from that. Returns `None` if we can't find
143144
/// one (e.g., this is just some random part of the CFG).
144145
pub(super) fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
145-
self.to_error_region_vid(r).and_then(|r| self.regioncx.region_definition(r).external_name)
146+
self.to_error_region_vid(r).and_then(|r| self.region_definition(r).external_name)
146147
}
147148

148149
/// Returns the `RegionVid` corresponding to the region returned by
149150
/// `to_error_region`.
150151
pub(super) fn to_error_region_vid(&self, r: RegionVid) -> Option<RegionVid> {
151-
if self.regioncx.universal_regions().is_universal_region(r) {
152+
if self.universal_regions().is_universal_region(r) {
152153
Some(r)
153154
} else {
154155
// We just want something nameable, even if it's not
155156
// actually an upper bound.
156-
let upper_bound = self.regioncx.approx_universal_upper_bound(r);
157+
let upper_bound = self.approx_universal_upper_bound(r);
157158

158-
if self.regioncx.upper_bound_in_region_scc(r, upper_bound) {
159+
if self.upper_bound_in_region_scc(r, upper_bound) {
159160
self.to_error_region_vid(upper_bound)
160161
} else {
161162
None
@@ -179,14 +180,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
179180
if let Some(r) = self.to_error_region(fr)
180181
&& let ty::ReLateParam(late_param) = r.kind()
181182
&& let ty::LateParamRegionKind::ClosureEnv = late_param.kind
182-
&& let DefiningTy::Closure(_, args) = self.regioncx.universal_regions().defining_ty
183+
&& let DefiningTy::Closure(_, args) = self.universal_regions().defining_ty
183184
{
184185
return args.as_closure().kind() == ty::ClosureKind::FnMut;
185186
}
186187

187188
false
188189
}
190+
}
189191

192+
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
190193
// For generic associated types (GATs) which implied 'static requirement
191194
// from higher-ranked trait bounds (HRTB). Try to locate span of the trait
192195
// and the span which bounded to the trait for adding 'static lifetime suggestion
@@ -309,12 +312,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
309312
RegionErrorKind::TypeTestError { type_test } => {
310313
// Try to convert the lower-bound region into something named we can print for
311314
// the user.
312-
let lower_bound_region = self.to_error_region(type_test.lower_bound);
315+
let lower_bound_region = self.regioncx.to_error_region(type_test.lower_bound);
313316

314317
let type_test_span = type_test.span;
315318

316319
if let Some(lower_bound_region) = lower_bound_region {
317-
let generic_ty = self.name_regions(
320+
let generic_ty = self.regioncx.name_regions(
318321
self.infcx.tcx,
319322
type_test.generic_kind.to_ty(self.infcx.tcx),
320323
);
@@ -324,7 +327,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
324327
self.body.source.def_id().expect_local(),
325328
type_test_span,
326329
Some(origin),
327-
self.name_regions(self.infcx.tcx, type_test.generic_kind),
330+
self.regioncx.name_regions(self.infcx.tcx, type_test.generic_kind),
328331
lower_bound_region,
329332
));
330333
} else {
@@ -450,7 +453,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
450453
debug!("report_region_error: category={:?} {:?} {:?}", category, cause, variance_info);
451454

452455
// Check if we can use one of the "nice region errors".
453-
if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) {
456+
if let (Some(f), Some(o)) =
457+
(self.regioncx.to_error_region(fr), self.regioncx.to_error_region(outlived_fr))
458+
{
454459
let infer_err = self.infcx.err_ctxt();
455460
let nice =
456461
NiceRegionError::new_from_span(&infer_err, self.mir_def_id(), cause.span, o, f);
@@ -481,7 +486,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
481486
d.note("meoow :c");
482487
d
483488
}
484-
(ConstraintCategory::Return(kind), true, false) if self.is_closure_fn_mut(fr) => {
489+
(ConstraintCategory::Return(kind), true, false)
490+
if self.regioncx.is_closure_fn_mut(fr) =>
491+
{
485492
self.report_fnmut_error(&errci, kind)
486493
}
487494
(ConstraintCategory::Assignment, true, false)
@@ -736,7 +743,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
736743
// Only show an extra note if we can find an 'error region' for both of the region
737744
// variables. This avoids showing a noisy note that just mentions 'synthetic' regions
738745
// that don't help the user understand the error.
739-
match (self.to_error_region(errci.fr), self.to_error_region(errci.outlived_fr)) {
746+
match (
747+
self.regioncx.to_error_region(errci.fr),
748+
self.regioncx.to_error_region(errci.outlived_fr),
749+
) {
740750
(Some(f), Some(o)) => {
741751
self.maybe_suggest_constrain_dyn_trait_impl(&mut diag, f, o, category);
742752

@@ -842,7 +852,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
842852
outlived_fr: RegionVid,
843853
) {
844854
if let (Some(f), Some(outlived_f)) =
845-
(self.to_error_region(fr), self.to_error_region(outlived_fr))
855+
(self.regioncx.to_error_region(fr), self.regioncx.to_error_region(outlived_fr))
846856
{
847857
if outlived_f.kind() != ty::ReStatic {
848858
return;
@@ -1013,7 +1023,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
10131023
}
10141024

10151025
fn suggest_adding_lifetime_params(&self, diag: &mut Diag<'_>, sub: RegionVid, sup: RegionVid) {
1016-
let (Some(sub), Some(sup)) = (self.to_error_region(sub), self.to_error_region(sup)) else {
1026+
let (Some(sub), Some(sup)) =
1027+
(self.regioncx.to_error_region(sub), self.regioncx.to_error_region(sup))
1028+
else {
10171029
return;
10181030
};
10191031

compiler/rustc_borrowck/src/diagnostics/region_name.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
283283
/// named variants.
284284
#[instrument(level = "trace", skip(self))]
285285
fn give_name_from_error_region(&self, fr: RegionVid) -> Option<RegionName> {
286-
let error_region = self.to_error_region(fr)?;
286+
let error_region = self.regioncx.to_error_region(fr)?;
287287

288288
let tcx = self.infcx.tcx;
289289

@@ -1015,7 +1015,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
10151015
&self,
10161016
fr: RegionVid,
10171017
) -> Option<RegionName> {
1018-
let ty::ReEarlyParam(region) = self.to_error_region(fr)?.kind() else {
1018+
let ty::ReEarlyParam(region) = self.regioncx.to_error_region(fr)?.kind() else {
10191019
return None;
10201020
};
10211021
if region.is_named() {
@@ -1050,7 +1050,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
10501050
&self,
10511051
fr: RegionVid,
10521052
) -> Option<RegionName> {
1053-
let ty::ReEarlyParam(region) = self.to_error_region(fr)?.kind() else {
1053+
let ty::ReEarlyParam(region) = self.regioncx.to_error_region(fr)?.kind() else {
10541054
return None;
10551055
};
10561056
if region.is_named() {

compiler/rustc_borrowck/src/lib.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use rustc_mir_dataflow::points::DenseLocationMap;
4848
use rustc_mir_dataflow::{Analysis, EntryStates, Results, ResultsVisitor, visit_results};
4949
use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT};
5050
use rustc_span::{ErrorGuaranteed, Span, Symbol};
51+
use rustc_trait_selection::traits::query::type_op::{QueryTypeOp, TypeOp, TypeOpOutput};
5152
use smallvec::SmallVec;
5253
use tracing::{debug, instrument};
5354

@@ -323,7 +324,6 @@ fn borrowck_collect_region_constraints<'tcx>(
323324
let input_promoted: &IndexSlice<_, _> = &promoted.borrow();
324325
if let Some(e) = input_body.tainted_by_errors {
325326
infcx.set_tainted_by_errors(e);
326-
root_cx.set_tainted_by_errors(e);
327327
}
328328

329329
// Replace all regions with fresh inference variables. This
@@ -571,15 +571,16 @@ fn borrowck_check_region_constraints<'tcx>(
571571

572572
debug!("mbcx.used_mut: {:?}", mbcx.used_mut);
573573
mbcx.lint_unused_mut();
574-
if let Some(guar) = mbcx.emit_errors() {
575-
mbcx.root_cx.set_tainted_by_errors(guar);
576-
}
577574

578575
let result = PropagatedBorrowCheckResults {
579576
closure_requirements: opt_closure_req,
580577
used_mut_upvars: mbcx.used_mut_upvars,
581578
};
582579

580+
if let Some(guar) = mbcx.diags_buffer.emit_errors().or(infcx.tainted_by_errors()) {
581+
root_cx.set_tainted_by_errors(guar);
582+
}
583+
583584
if let Some(consumer) = &mut root_cx.consumer {
584585
consumer.insert_body(
585586
def,
@@ -707,6 +708,14 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
707708

708709
next_region
709710
}
711+
712+
fn fully_perform<Q: QueryTypeOp<'tcx> + TypeVisitable<TyCtxt<'tcx>>>(
713+
&self,
714+
q: Q,
715+
span: Span,
716+
) -> Result<TypeOpOutput<'tcx, ty::ParamEnvAnd<'tcx, Q>>, ErrorGuaranteed> {
717+
self.param_env.and(q).fully_perform(&self.infcx, self.root_def_id, span)
718+
}
710719
}
711720

712721
impl<'tcx> Deref for BorrowckInferCtxt<'tcx> {
@@ -718,7 +727,7 @@ impl<'tcx> Deref for BorrowckInferCtxt<'tcx> {
718727
}
719728

720729
pub(crate) struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
721-
root_cx: &'a mut BorrowCheckRootCtxt<'tcx>,
730+
root_cx: &'a BorrowCheckRootCtxt<'tcx>,
722731
infcx: &'infcx BorrowckInferCtxt<'tcx>,
723732
body: &'a Body<'tcx>,
724733
move_data: &'a MoveData<'tcx>,

compiler/rustc_borrowck/src/nll.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub(crate) fn compute_closure_requirements_modulo_opaques<'tcx>(
111111
///
112112
/// This may result in errors being reported.
113113
pub(crate) fn compute_regions<'tcx>(
114-
root_cx: &mut BorrowCheckRootCtxt<'tcx>,
114+
root_cx: &BorrowCheckRootCtxt<'tcx>,
115115
infcx: &BorrowckInferCtxt<'tcx>,
116116
body: &Body<'tcx>,
117117
location_table: &PoloniusLocationTable,

compiler/rustc_borrowck/src/root_cx.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
7272
}
7373

7474
pub(super) fn used_mut_upvars(
75-
&mut self,
75+
&self,
7676
nested_body_def_id: LocalDefId,
7777
) -> &SmallVec<[FieldIdx; 8]> {
7878
&self.propagated_borrowck_results[&nested_body_def_id].used_mut_upvars

compiler/rustc_borrowck/src/type_check/constraint_conversion.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_middle::ty::{
1111
self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, elaborate, fold_regions,
1212
};
1313
use rustc_span::Span;
14-
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
14+
use rustc_trait_selection::traits::query::type_op::TypeOpOutput;
1515
use tracing::{debug, instrument};
1616

1717
use crate::constraints::OutlivesConstraint;
@@ -287,11 +287,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
287287
ConstraintCategory<'tcx>,
288288
)>,
289289
) -> Ty<'tcx> {
290-
match self.infcx.param_env.and(DeeplyNormalize { value: ty }).fully_perform(
291-
self.infcx,
292-
self.infcx.root_def_id,
293-
self.span,
294-
) {
290+
match self.infcx.fully_perform(DeeplyNormalize { value: ty }, self.span) {
295291
Ok(TypeOpOutput { output: ty, constraints, .. }) => {
296292
// FIXME(higher_ranked_auto): What should we do with the assumptions here?
297293
if let Some(QueryRegionConstraints { constraints, assumptions: _ }) = constraints {

0 commit comments

Comments
 (0)