Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 8365ad1

Browse files
committed
handle opaque types before region inference
1 parent e255a9b commit 8365ad1

File tree

45 files changed

+1094
-1236
lines changed

Some content is hidden

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

45 files changed

+1094
-1236
lines changed

‎compiler/rustc_borrowck/src/dataflow.rs‎

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::fmt;
22

33
use rustc_data_structures::fx::FxIndexMap;
4-
use rustc_data_structures::graph;
54
use rustc_index::bit_set::{DenseBitSet, MixedBitSet};
65
use rustc_middle::mir::{
76
self, BasicBlock, Body, CallReturnPlaces, Location, Place, TerminatorEdges,
@@ -317,9 +316,8 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
317316
loans_out_of_scope_at_location: FxIndexMap::default(),
318317
};
319318
for (loan_idx, loan_data) in borrow_set.iter_enumerated() {
320-
let issuing_region = loan_data.region;
321319
let loan_issued_at = loan_data.reserve_location;
322-
prec.precompute_loans_out_of_scope(loan_idx, issuing_region,loan_issued_at);
320+
prec.precompute_loans_out_of_scope(loan_idx, loan_issued_at);
323321
}
324322

325323
prec.loans_out_of_scope_at_location
@@ -328,45 +326,7 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
328326
/// Loans are in scope while they are live: whether they are contained within any live region.
329327
/// In the location-insensitive analysis, a loan will be contained in a region if the issuing
330328
/// region can reach it in the subset graph. So this is a reachability problem.
331-
fn precompute_loans_out_of_scope(
332-
&mut self,
333-
loan_idx: BorrowIndex,
334-
issuing_region: RegionVid,
335-
loan_issued_at: Location,
336-
) {
337-
let sccs = self.regioncx.constraint_sccs();
338-
let universal_regions = self.regioncx.universal_regions();
339-
340-
// The loop below was useful for the location-insensitive analysis but shouldn't be
341-
// impactful in the location-sensitive case. It seems that it does, however, as without it a
342-
// handful of tests fail. That likely means some liveness or outlives data related to choice
343-
// regions is missing
344-
// FIXME: investigate the impact of loans traversing applied member constraints and why some
345-
// tests fail otherwise.
346-
//
347-
// We first handle the cases where the loan doesn't go out of scope, depending on the
348-
// issuing region's successors.
349-
for successor in graph::depth_first_search(&self.regioncx.region_graph(), issuing_region) {
350-
// Via applied member constraints
351-
//
352-
// The issuing region can flow into the choice regions, and they are either:
353-
// - placeholders or free regions themselves,
354-
// - or also transitively outlive a free region.
355-
//
356-
// That is to say, if there are applied member constraints here, the loan escapes the
357-
// function and cannot go out of scope. We could early return here.
358-
//
359-
// For additional insurance via fuzzing and crater, we verify that the constraint's min
360-
// choice indeed escapes the function. In the future, we could e.g. turn this check into
361-
// a debug assert and early return as an optimization.
362-
let scc = sccs.scc(successor);
363-
for constraint in self.regioncx.applied_member_constraints(scc) {
364-
if universal_regions.is_universal_region(constraint.min_choice) {
365-
return;
366-
}
367-
}
368-
}
369-
329+
fn precompute_loans_out_of_scope(&mut self, loan_idx: BorrowIndex, loan_issued_at: Location) {
370330
let first_block = loan_issued_at.block;
371331
let first_bb_data = &self.body.basic_blocks[first_block];
372332

‎compiler/rustc_borrowck/src/diagnostics/opaque_types.rs‎

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ use rustc_middle::mir::{self, ConstraintCategory, Location};
1313
use rustc_middle::ty::{
1414
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
1515
};
16+
use rustc_span::Span;
17+
use rustc_trait_selection::error_reporting::infer::region::unexpected_hidden_region_diagnostic;
1618
use rustc_trait_selection::errors::impl_trait_overcapture_suggestion;
1719

1820
use crate::MirBorrowckCtxt;
@@ -26,13 +28,61 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
2628
if errors.is_empty() {
2729
return;
2830
}
31+
32+
let infcx = self.infcx;
2933
let mut guar = None;
34+
let mut last_unexpected_hidden_region: Option<(Span, Ty<'_>, ty::OpaqueTypeKey<'tcx>)> =
35+
None;
3036
for error in errors {
3137
guar = Some(match error {
32-
DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err) => err.report(self.infcx),
38+
DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err) => err.report(infcx),
3339
DeferredOpaqueTypeError::LifetimeMismatchOpaqueParam(err) => {
34-
self.infcx.dcx().emit_err(err)
40+
infcx.dcx().emit_err(err)
41+
}
42+
DeferredOpaqueTypeError::UnexpectedHiddenRegion {
43+
opaque_type_key,
44+
hidden_type,
45+
member_region,
46+
} => {
47+
let named_ty =
48+
self.regioncx.name_regions_for_member_constraint(infcx.tcx, hidden_type.ty);
49+
let named_key = self
50+
.regioncx
51+
.name_regions_for_member_constraint(infcx.tcx, opaque_type_key);
52+
let named_region =
53+
self.regioncx.name_regions_for_member_constraint(infcx.tcx, member_region);
54+
let diag = unexpected_hidden_region_diagnostic(
55+
infcx,
56+
self.mir_def_id(),
57+
hidden_type.span,
58+
named_ty,
59+
named_region,
60+
named_key,
61+
);
62+
if last_unexpected_hidden_region
63+
!= Some((hidden_type.span, named_ty, named_key))
64+
{
65+
last_unexpected_hidden_region =
66+
Some((hidden_type.span, named_ty, named_key));
67+
diag.emit()
68+
} else {
69+
diag.delay_as_bug()
70+
}
3571
}
72+
DeferredOpaqueTypeError::NonDefiningUseInDefiningScope {
73+
span,
74+
opaque_type_key,
75+
} => infcx.dcx().span_err(
76+
span,
77+
format!(
78+
"non-defining use of `{}` in the defining scope",
79+
Ty::new_opaque(
80+
infcx.tcx,
81+
opaque_type_key.def_id.to_def_id(),
82+
opaque_type_key.args
83+
)
84+
),
85+
),
3686
});
3787
}
3888
let guar = guar.unwrap();

‎compiler/rustc_borrowck/src/diagnostics/region_errors.rs‎

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use rustc_trait_selection::error_reporting::infer::nice_region_error::{
2323
self, HirTraitObjectVisitor, NiceRegionError, TraitObjectVisitor, find_anon_type,
2424
find_param_with_region, suggest_adding_lifetime_params,
2525
};
26-
use rustc_trait_selection::error_reporting::infer::region::unexpected_hidden_region_diagnostic;
2726
use rustc_trait_selection::infer::InferCtxtExt;
2827
use rustc_trait_selection::traits::{Obligation, ObligationCtxt};
2928
use tracing::{debug, instrument, trace};
@@ -105,18 +104,6 @@ pub(crate) enum RegionErrorKind<'tcx> {
105104
/// A generic bound failure for a type test (`T: 'a`).
106105
TypeTestError { type_test: TypeTest<'tcx> },
107106

108-
/// An unexpected hidden region for an opaque type.
109-
UnexpectedHiddenRegion {
110-
/// The span for the member constraint.
111-
span: Span,
112-
/// The hidden type.
113-
hidden_ty: Ty<'tcx>,
114-
/// The opaque type.
115-
key: ty::OpaqueTypeKey<'tcx>,
116-
/// The unexpected region.
117-
member_region: ty::Region<'tcx>,
118-
},
119-
120107
/// Higher-ranked subtyping error.
121108
BoundUniversalRegionError {
122109
/// The placeholder free region.
@@ -323,11 +310,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
323310
pub(crate) fn report_region_errors(&mut self, nll_errors: RegionErrors<'tcx>) {
324311
// Iterate through all the errors, producing a diagnostic for each one. The diagnostics are
325312
// buffered in the `MirBorrowckCtxt`.
326-
327313
let mut outlives_suggestion = OutlivesSuggestionBuilder::default();
328-
let mut last_unexpected_hidden_region: Option<(Span, Ty<'_>, ty::OpaqueTypeKey<'tcx>)> =
329-
None;
330-
331314
for (nll_error, _) in nll_errors.into_iter() {
332315
match nll_error {
333316
RegionErrorKind::TypeTestError { type_test } => {
@@ -378,30 +361,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
378361
}
379362
}
380363

381-
RegionErrorKind::UnexpectedHiddenRegion { span, hidden_ty, key, member_region } => {
382-
let named_ty =
383-
self.regioncx.name_regions_for_member_constraint(self.infcx.tcx, hidden_ty);
384-
let named_key =
385-
self.regioncx.name_regions_for_member_constraint(self.infcx.tcx, key);
386-
let named_region = self
387-
.regioncx
388-
.name_regions_for_member_constraint(self.infcx.tcx, member_region);
389-
let diag = unexpected_hidden_region_diagnostic(
390-
self.infcx,
391-
self.mir_def_id(),
392-
span,
393-
named_ty,
394-
named_region,
395-
named_key,
396-
);
397-
if last_unexpected_hidden_region != Some((span, named_ty, named_key)) {
398-
self.buffer_error(diag);
399-
last_unexpected_hidden_region = Some((span, named_ty, named_key));
400-
} else {
401-
diag.delay_as_bug();
402-
}
403-
}
404-
405364
RegionErrorKind::BoundUniversalRegionError {
406365
longer_fr,
407366
placeholder,

‎compiler/rustc_borrowck/src/handle_placeholders.rs‎

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use tracing::debug;
1515
use crate::constraints::{ConstraintSccIndex, OutlivesConstraintSet};
1616
use crate::consumers::OutlivesConstraint;
1717
use crate::diagnostics::UniverseInfo;
18-
use crate::member_constraints::MemberConstraintSet;
1918
use crate::region_infer::values::{LivenessValues, PlaceholderIndices};
2019
use crate::region_infer::{ConstraintSccs, RegionDefinition, Representative, TypeTest};
2120
use crate::ty::VarianceDiagInfo;
@@ -30,7 +29,6 @@ pub(crate) struct LoweredConstraints<'tcx> {
3029
pub(crate) constraint_sccs: Sccs<RegionVid, ConstraintSccIndex>,
3130
pub(crate) definitions: Frozen<IndexVec<RegionVid, RegionDefinition<'tcx>>>,
3231
pub(crate) scc_annotations: IndexVec<ConstraintSccIndex, RegionTracker>,
33-
pub(crate) member_constraints: MemberConstraintSet<'tcx, RegionVid>,
3432
pub(crate) outlives_constraints: Frozen<OutlivesConstraintSet<'tcx>>,
3533
pub(crate) type_tests: Vec<TypeTest<'tcx>>,
3634
pub(crate) liveness_constraints: LivenessValues,
@@ -147,9 +145,10 @@ impl scc::Annotation for RegionTracker {
147145

148146
/// Determines if the region variable definitions contain
149147
/// placeholders, and compute them for later use.
150-
fnregion_definitions<'tcx>(
151-
universal_regions:&UniversalRegions<'tcx>,
148+
// FIXME: This is also used by opaque type handling. Move it to a separate file.
149+
pub(super)fnregion_definitions<'tcx>(
152150
infcx: &BorrowckInferCtxt<'tcx>,
151+
universal_regions: &UniversalRegions<'tcx>,
153152
) -> (Frozen<IndexVec<RegionVid, RegionDefinition<'tcx>>>, bool) {
154153
let var_infos = infcx.get_region_var_infos();
155154
// Create a RegionDefinition for each inference variable. This happens here because
@@ -213,14 +212,13 @@ pub(crate) fn compute_sccs_applying_placeholder_outlives_constraints<'tcx>(
213212
infcx: &BorrowckInferCtxt<'tcx>,
214213
) -> LoweredConstraints<'tcx> {
215214
let universal_regions = &universal_region_relations.universal_regions;
216-
let (definitions, has_placeholders) = region_definitions(universal_regions, infcx);
215+
let (definitions, has_placeholders) = region_definitions(infcx, universal_regions);
217216

218217
let MirTypeckRegionConstraints {
219218
placeholder_indices,
220219
placeholder_index_to_region: _,
221220
liveness_constraints,
222221
mut outlives_constraints,
223-
member_constraints,
224222
universe_causes,
225223
type_tests,
226224
} = constraints;
@@ -246,7 +244,6 @@ pub(crate) fn compute_sccs_applying_placeholder_outlives_constraints<'tcx>(
246244

247245
return LoweredConstraints {
248246
type_tests,
249-
member_constraints,
250247
constraint_sccs,
251248
scc_annotations: scc_annotations.scc_to_annotation,
252249
definitions,
@@ -283,7 +280,6 @@ pub(crate) fn compute_sccs_applying_placeholder_outlives_constraints<'tcx>(
283280
constraint_sccs,
284281
definitions,
285282
scc_annotations,
286-
member_constraints,
287283
outlives_constraints: Frozen::freeze(outlives_constraints),
288284
type_tests,
289285
liveness_constraints,

‎compiler/rustc_borrowck/src/lib.rs‎

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ mod dataflow;
7878
mod def_use;
7979
mod diagnostics;
8080
mod handle_placeholders;
81-
mod member_constraints;
8281
mod nll;
8382
mod path_utils;
8483
mod place_ext;
@@ -335,9 +334,10 @@ fn do_mir_borrowck<'tcx>(
335334

336335
// Run the MIR type-checker.
337336
let MirTypeckResults {
338-
constraints,
337+
mutconstraints,
339338
universal_region_relations,
340-
opaque_type_values,
339+
region_bound_pairs,
340+
known_type_outlives_obligations,
341341
polonius_context,
342342
} = type_check::type_check(
343343
root_cx,
@@ -352,6 +352,17 @@ fn do_mir_borrowck<'tcx>(
352352
Rc::clone(&location_map),
353353
);
354354

355+
let opaque_type_errors = region_infer::opaque_types::handle_opaque_type_uses(
356+
root_cx,
357+
&infcx,
358+
&body,
359+
&universal_region_relations,
360+
&region_bound_pairs,
361+
&known_type_outlives_obligations,
362+
&location_map,
363+
&mut constraints,
364+
);
365+
355366
// Compute non-lexical lifetimes using the constraints computed
356367
// by typechecking the MIR body.
357368
let nll::NllOutput {
@@ -375,8 +386,6 @@ fn do_mir_borrowck<'tcx>(
375386
polonius_context,
376387
);
377388

378-
let opaque_type_errors = regioncx.infer_opaque_types(root_cx, &infcx, opaque_type_values);
379-
380389
// Dump MIR results into a file, if that is enabled. This lets us
381390
// write unit-tests, as well as helping with debugging.
382391
nll::dump_nll_mir(&infcx, body, &regioncx, &opt_closure_req, &borrow_set);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /