Skip to content

Commit b81c599

Browse files
authored
Unrolled build for #145115
Rollup merge of #145115 - lcnr:less-borrowck-tainting, r=compiler-errors defer opaque type errors, generally greatly reduce tainting fixes the test for #135528, does not actually fix that issue properly. This is useful as it causes the migration to #139587 to be a lot easier.
2 parents 2de2456 + 4eee556 commit b81c599

21 files changed

+210
-101
lines changed

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ mod conflict_errors;
5151
mod explain_borrow;
5252
mod move_errors;
5353
mod mutability_errors;
54-
mod opaque_suggestions;
54+
mod opaque_types;
5555
mod region_errors;
5656

5757
pub(crate) use bound_region_errors::{ToUniverseInfo, UniverseInfo};

compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs renamed to compiler/rustc_borrowck/src/diagnostics/opaque_types.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,28 @@ use rustc_trait_selection::errors::impl_trait_overcapture_suggestion;
1818
use crate::MirBorrowckCtxt;
1919
use crate::borrow_set::BorrowData;
2020
use crate::consumers::RegionInferenceContext;
21+
use crate::region_infer::opaque_types::DeferredOpaqueTypeError;
2122
use crate::type_check::Locations;
2223

2324
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
25+
pub(crate) fn report_opaque_type_errors(&mut self, errors: Vec<DeferredOpaqueTypeError<'tcx>>) {
26+
if errors.is_empty() {
27+
return;
28+
}
29+
let mut guar = None;
30+
for error in errors {
31+
guar = Some(match error {
32+
DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err) => err.report(self.infcx),
33+
DeferredOpaqueTypeError::LifetimeMismatchOpaqueParam(err) => {
34+
self.infcx.dcx().emit_err(err)
35+
}
36+
});
37+
}
38+
let guar = guar.unwrap();
39+
self.root_cx.set_tainted_by_errors(guar);
40+
self.infcx.set_tainted_by_errors(guar);
41+
}
42+
2443
/// Try to note when an opaque is involved in a borrowck error and that
2544
/// opaque captures lifetimes due to edition 2024.
2645
// FIXME: This code is otherwise somewhat general, and could easily be adapted

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,6 @@ impl<'tcx> RegionErrors<'tcx> {
9292
) -> impl Iterator<Item = (RegionErrorKind<'tcx>, ErrorGuaranteed)> {
9393
self.0.into_iter()
9494
}
95-
pub(crate) fn has_errors(&self) -> Option<ErrorGuaranteed> {
96-
self.0.get(0).map(|x| x.1)
97-
}
9895
}
9996

10097
impl std::fmt::Debug for RegionErrors<'_> {

compiler/rustc_borrowck/src/handle_placeholders.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -216,22 +216,11 @@ pub(crate) fn compute_sccs_applying_placeholder_outlives_constraints<'tcx>(
216216
placeholder_index_to_region: _,
217217
liveness_constraints,
218218
mut outlives_constraints,
219-
mut member_constraints,
219+
member_constraints,
220220
universe_causes,
221221
type_tests,
222222
} = constraints;
223223

224-
if let Some(guar) = universal_regions.tainted_by_errors() {
225-
debug!("Universal regions tainted by errors; removing constraints!");
226-
// Suppress unhelpful extra errors in `infer_opaque_types` by clearing out all
227-
// outlives bounds that we may end up checking.
228-
outlives_constraints = Default::default();
229-
member_constraints = Default::default();
230-
231-
// Also taint the entire scope.
232-
infcx.set_tainted_by_errors(guar);
233-
}
234-
235224
let fr_static = universal_regions.fr_static;
236225
let compute_sccs =
237226
|constraints: &OutlivesConstraintSet<'tcx>,

compiler/rustc_borrowck/src/lib.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ fn do_mir_borrowck<'tcx>(
375375
polonius_context,
376376
);
377377

378-
regioncx.infer_opaque_types(root_cx, &infcx, opaque_type_values);
378+
let opaque_type_errors = regioncx.infer_opaque_types(root_cx, &infcx, opaque_type_values);
379379

380380
// Dump MIR results into a file, if that is enabled. This lets us
381381
// write unit-tests, as well as helping with debugging.
@@ -471,7 +471,11 @@ fn do_mir_borrowck<'tcx>(
471471
};
472472

473473
// Compute and report region errors, if any.
474-
mbcx.report_region_errors(nll_errors);
474+
if nll_errors.is_empty() {
475+
mbcx.report_opaque_type_errors(opaque_type_errors);
476+
} else {
477+
mbcx.report_region_errors(nll_errors);
478+
}
475479

476480
let (mut flow_analysis, flow_entry_states) =
477481
get_flow_results(tcx, body, &move_data, &borrow_set, &regioncx);

compiler/rustc_borrowck/src/nll.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,6 @@ pub(crate) fn compute_regions<'tcx>(
148148
let (closure_region_requirements, nll_errors) =
149149
regioncx.solve(infcx, body, polonius_output.clone());
150150

151-
if let Some(guar) = nll_errors.has_errors() {
152-
// Suppress unhelpful extra errors in `infer_opaque_types`.
153-
infcx.set_tainted_by_errors(guar);
154-
}
155-
156151
NllOutput {
157152
regioncx,
158153
polonius_input: polonius_facts.map(Box::new),

compiler/rustc_borrowck/src/region_infer/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use crate::{
4444

4545
mod dump_mir;
4646
mod graphviz;
47-
mod opaque_types;
47+
pub(crate) mod opaque_types;
4848
mod reverse_sccs;
4949

5050
pub(crate) mod values;

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,21 @@ use rustc_middle::ty::{
66
TypeVisitableExt, fold_regions,
77
};
88
use rustc_span::Span;
9-
use rustc_trait_selection::opaque_types::check_opaque_type_parameter_valid;
9+
use rustc_trait_selection::opaque_types::{
10+
InvalidOpaqueTypeArgs, check_opaque_type_parameter_valid,
11+
};
1012
use tracing::{debug, instrument};
1113

1214
use super::RegionInferenceContext;
1315
use crate::BorrowCheckRootCtxt;
1416
use crate::session_diagnostics::LifetimeMismatchOpaqueParam;
1517
use crate::universal_regions::RegionClassification;
1618

19+
pub(crate) enum DeferredOpaqueTypeError<'tcx> {
20+
InvalidOpaqueTypeArgs(InvalidOpaqueTypeArgs<'tcx>),
21+
LifetimeMismatchOpaqueParam(LifetimeMismatchOpaqueParam<'tcx>),
22+
}
23+
1724
impl<'tcx> RegionInferenceContext<'tcx> {
1825
/// Resolve any opaque types that were encountered while borrow checking
1926
/// this item. This is then used to get the type in the `type_of` query.
@@ -58,13 +65,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
5865
///
5966
/// [rustc-dev-guide chapter]:
6067
/// https://rustc-dev-guide.rust-lang.org/opaque-types-region-infer-restrictions.html
61-
#[instrument(level = "debug", skip(self, root_cx, infcx), ret)]
68+
#[instrument(level = "debug", skip(self, root_cx, infcx))]
6269
pub(crate) fn infer_opaque_types(
6370
&self,
6471
root_cx: &mut BorrowCheckRootCtxt<'tcx>,
6572
infcx: &InferCtxt<'tcx>,
6673
opaque_ty_decls: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
67-
) {
74+
) -> Vec<DeferredOpaqueTypeError<'tcx>> {
75+
let mut errors = Vec::new();
6876
let mut decls_modulo_regions: FxIndexMap<OpaqueTypeKey<'tcx>, (OpaqueTypeKey<'tcx>, Span)> =
6977
FxIndexMap::default();
7078

@@ -124,8 +132,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
124132
});
125133
debug!(?concrete_type);
126134

127-
let ty =
128-
infcx.infer_opaque_definition_from_instantiation(opaque_type_key, concrete_type);
135+
let ty = match infcx
136+
.infer_opaque_definition_from_instantiation(opaque_type_key, concrete_type)
137+
{
138+
Ok(ty) => ty,
139+
Err(err) => {
140+
errors.push(DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err));
141+
continue;
142+
}
143+
};
129144

130145
// Sometimes, when the hidden type is an inference variable, it can happen that
131146
// the hidden type becomes the opaque type itself. In this case, this was an opaque
@@ -149,25 +164,27 @@ impl<'tcx> RegionInferenceContext<'tcx> {
149164
// non-region parameters. This is necessary because within the new solver we perform
150165
// various query operations modulo regions, and thus could unsoundly select some impls
151166
// that don't hold.
152-
if !ty.references_error()
153-
&& let Some((prev_decl_key, prev_span)) = decls_modulo_regions.insert(
154-
infcx.tcx.erase_regions(opaque_type_key),
155-
(opaque_type_key, concrete_type.span),
156-
)
157-
&& let Some((arg1, arg2)) = std::iter::zip(
158-
prev_decl_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg),
159-
opaque_type_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg),
160-
)
161-
.find(|(arg1, arg2)| arg1 != arg2)
167+
if let Some((prev_decl_key, prev_span)) = decls_modulo_regions.insert(
168+
infcx.tcx.erase_regions(opaque_type_key),
169+
(opaque_type_key, concrete_type.span),
170+
) && let Some((arg1, arg2)) = std::iter::zip(
171+
prev_decl_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg),
172+
opaque_type_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg),
173+
)
174+
.find(|(arg1, arg2)| arg1 != arg2)
162175
{
163-
infcx.dcx().emit_err(LifetimeMismatchOpaqueParam {
164-
arg: arg1,
165-
prev: arg2,
166-
span: prev_span,
167-
prev_span: concrete_type.span,
168-
});
176+
errors.push(DeferredOpaqueTypeError::LifetimeMismatchOpaqueParam(
177+
LifetimeMismatchOpaqueParam {
178+
arg: arg1,
179+
prev: arg2,
180+
span: prev_span,
181+
prev_span: concrete_type.span,
182+
},
183+
));
169184
}
170185
}
186+
187+
errors
171188
}
172189

173190
/// Map the regions in the type to named regions. This is similar to what
@@ -260,19 +277,13 @@ impl<'tcx> InferCtxt<'tcx> {
260277
&self,
261278
opaque_type_key: OpaqueTypeKey<'tcx>,
262279
instantiated_ty: OpaqueHiddenType<'tcx>,
263-
) -> Ty<'tcx> {
264-
if let Some(e) = self.tainted_by_errors() {
265-
return Ty::new_error(self.tcx, e);
266-
}
267-
268-
if let Err(err) = check_opaque_type_parameter_valid(
280+
) -> Result<Ty<'tcx>, InvalidOpaqueTypeArgs<'tcx>> {
281+
check_opaque_type_parameter_valid(
269282
self,
270283
opaque_type_key,
271284
instantiated_ty.span,
272285
DefiningScopeKind::MirBorrowck,
273-
) {
274-
return Ty::new_error(self.tcx, err.report(self));
275-
}
286+
)?;
276287

277288
let definition_ty = instantiated_ty
278289
.remap_generic_params_to_declaration_params(
@@ -282,10 +293,7 @@ impl<'tcx> InferCtxt<'tcx> {
282293
)
283294
.ty;
284295

285-
if let Err(e) = definition_ty.error_reported() {
286-
return Ty::new_error(self.tcx, e);
287-
}
288-
289-
definition_ty
296+
definition_ty.error_reported()?;
297+
Ok(definition_ty)
290298
}
291299
}

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,17 @@ pub(crate) fn type_check<'tcx>(
182182
)
183183
});
184184

185+
// In case type check encountered an error region, we suppress unhelpful extra
186+
// errors in by clearing out all outlives bounds that we may end up checking.
187+
if let Some(guar) = universal_region_relations.universal_regions.encountered_re_error() {
188+
debug!("encountered an error region; removing constraints!");
189+
constraints.outlives_constraints = Default::default();
190+
constraints.member_constraints = Default::default();
191+
constraints.type_tests = Default::default();
192+
root_cx.set_tainted_by_errors(guar);
193+
infcx.set_tainted_by_errors(guar);
194+
}
195+
185196
MirTypeckResults {
186197
constraints,
187198
universal_region_relations,

compiler/rustc_borrowck/src/universal_regions.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ struct UniversalRegionIndices<'tcx> {
217217

218218
/// Whether we've encountered an error region. If we have, cancel all
219219
/// outlives errors, as they are likely bogus.
220-
pub tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
220+
pub encountered_re_error: Cell<Option<ErrorGuaranteed>>,
221221
}
222222

223223
#[derive(Debug, PartialEq)]
@@ -442,8 +442,8 @@ impl<'tcx> UniversalRegions<'tcx> {
442442
self.fr_fn_body
443443
}
444444

445-
pub(crate) fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
446-
self.indices.tainted_by_errors.get()
445+
pub(crate) fn encountered_re_error(&self) -> Option<ErrorGuaranteed> {
446+
self.indices.encountered_re_error.get()
447447
}
448448
}
449449

@@ -706,7 +706,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
706706
UniversalRegionIndices {
707707
indices: global_mapping.chain(arg_mapping).collect(),
708708
fr_static,
709-
tainted_by_errors: Cell::new(None),
709+
encountered_re_error: Cell::new(None),
710710
}
711711
}
712712

@@ -916,7 +916,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
916916
match r.kind() {
917917
ty::ReVar(..) => r.as_var(),
918918
ty::ReError(guar) => {
919-
self.tainted_by_errors.set(Some(guar));
919+
self.encountered_re_error.set(Some(guar));
920920
// We use the `'static` `RegionVid` because `ReError` doesn't actually exist in the
921921
// `UniversalRegionIndices`. This is fine because 1) it is a fallback only used if
922922
// errors are being emitted and 2) it leaves the happy path unaffected.

0 commit comments

Comments
 (0)