Skip to content

Commit 6cd0bc3

Browse files
committed
WIP
1 parent 197e49b commit 6cd0bc3

File tree

3 files changed

+73
-54
lines changed

3 files changed

+73
-54
lines changed

compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use rustc_traits::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_
2424
use tracing::{debug, instrument};
2525

2626
use crate::MirBorrowckCtxt;
27-
use crate::region_infer::values::RegionElement;
2827
use crate::session_diagnostics::{
2928
HigherRankedErrorCause, HigherRankedLifetimeError, HigherRankedSubtypeError,
3029
};
@@ -49,11 +48,12 @@ impl<'tcx> UniverseInfo<'tcx> {
4948
UniverseInfo::RelateTys { expected, found }
5049
}
5150

51+
/// Report an error where an element erroneously made its way into `placeholder`.
5252
pub(crate) fn report_erroneous_element(
5353
&self,
5454
mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
5555
placeholder: ty::PlaceholderRegion,
56-
error_element: RegionElement,
56+
error_element: Option<ty::PlaceholderRegion>,
5757
cause: ObligationCause<'tcx>,
5858
) {
5959
match *self {
@@ -145,52 +145,54 @@ pub(crate) trait TypeOpInfo<'tcx> {
145145
error_region: Option<ty::Region<'tcx>>,
146146
) -> Option<Diag<'infcx>>;
147147

148-
/// Constraints require that `error_element` appear in the
149-
/// values of `placeholder`, but this cannot be proven to
150-
/// hold. Report an error.
148+
/// Turn a placeholder region into a Region with its universe adjusted by
149+
/// the base universe.
150+
fn region_with_adjusted_universe(
151+
&self,
152+
placeholder: ty::PlaceholderRegion,
153+
tcx: TyCtxt<'tcx>,
154+
) -> ty::Region<'tcx> {
155+
let Some(adjusted_universe) =
156+
placeholder.universe.as_u32().checked_sub(self.base_universe().as_u32())
157+
else {
158+
unreachable!(
159+
"Could not adjust universe {:?} of {placeholder:?} by base universe {:?}",
160+
placeholder.universe,
161+
self.base_universe()
162+
);
163+
};
164+
ty::Region::new_placeholder(
165+
tcx,
166+
ty::Placeholder { universe: adjusted_universe.into(), bound: placeholder.bound },
167+
)
168+
}
169+
170+
/// Report an error where an erroneous element reaches `placeholder`.
171+
/// The erroneous element is either another placeholder that we provide,
172+
/// or we reverse engineer what happened later anyway.
151173
#[instrument(level = "debug", skip(self, mbcx))]
152174
fn report_erroneous_element(
153175
&self,
154176
mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
155177
placeholder: ty::PlaceholderRegion,
156-
error_element: RegionElement,
178+
error_element: Option<ty::PlaceholderRegion>,
157179
cause: ObligationCause<'tcx>,
158180
) {
159181
let tcx = mbcx.infcx.tcx;
160-
let base_universe = self.base_universe();
161-
debug!(?base_universe);
162-
163-
let Some(adjusted_universe) =
164-
placeholder.universe.as_u32().checked_sub(base_universe.as_u32())
165-
else {
166-
mbcx.buffer_error(self.fallback_error(tcx, cause.span));
167-
return;
168-
};
169182

170-
let placeholder_region = ty::Region::new_placeholder(
171-
tcx,
172-
ty::Placeholder { universe: adjusted_universe.into(), bound: placeholder.bound },
173-
);
174-
175-
let error_region = if let RegionElement::PlaceholderRegion(error_placeholder) =
176-
error_element
177-
{
178-
let adjusted_universe =
179-
error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32());
180-
adjusted_universe.map(|adjusted| {
181-
ty::Region::new_placeholder(
182-
tcx,
183-
ty::Placeholder { universe: adjusted.into(), bound: error_placeholder.bound },
184-
)
185-
})
186-
} else {
187-
None
188-
};
183+
// FIXME: these adjusted universes are not (always) the same ones as we compute
184+
// earlier. They probably should be, but the logic downstream is complicated,
185+
// and assumes they use whatever this is.
186+
//
187+
// In fact, this function throws away a lot of interesting information that would
188+
// probably allow bypassing lots of logic downstream for a much simpler flow.
189+
let placeholder_region = self.region_with_adjusted_universe(placeholder, tcx);
190+
let error_element = error_element.map(|e| self.region_with_adjusted_universe(e, tcx));
189191

190192
debug!(?placeholder_region);
191193

192194
let span = cause.span;
193-
let nice_error = self.nice_error(mbcx, cause, placeholder_region, error_region);
195+
let nice_error = self.nice_error(mbcx, cause, placeholder_region, error_element);
194196

195197
debug!(?nice_error);
196198
mbcx.buffer_error(nice_error.unwrap_or_else(|| self.fallback_error(tcx, span)));

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -415,25 +415,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
415415
longer_fr,
416416
placeholder,
417417
error_element,
418-
} => {
419-
let error_vid = self.regioncx.region_from_element(longer_fr, &error_element);
420-
421-
// Find the code to blame for the fact that `longer_fr` outlives `error_fr`.
422-
let cause = self
423-
.regioncx
424-
.best_blame_constraint(
425-
longer_fr,
426-
NllRegionVariableOrigin::Placeholder(placeholder),
427-
error_vid,
428-
)
429-
.0
430-
.cause;
431-
432-
let universe = placeholder.universe;
433-
let universe_info = self.regioncx.universe_info(universe);
434-
435-
universe_info.report_erroneous_element(self, placeholder, error_element, cause);
436-
}
418+
} => self.report_erroneous_rvid_reaches_placeholder(
419+
longer_fr,
420+
placeholder,
421+
self.regioncx.region_from_element(longer_fr, &error_element),
422+
),
437423
RegionErrorKind::PlaceholderOutlivesPlaceholder {
438424
rvid_a,
439425
rvid_b,

compiler/rustc_borrowck/src/lib.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2625,6 +2625,37 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
26252625
tcx.emit_node_span_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span })
26262626
}
26272627
}
2628+
2629+
/// Report that longer_fr: shorter_fr, which doesn't hold,
2630+
/// where longer_fr is a placeholder from `placeholder`.
2631+
fn report_erroneous_rvid_reaches_placeholder(
2632+
&mut self,
2633+
longer_fr: RegionVid,
2634+
placeholder: ty::Placeholder<ty::BoundRegion>,
2635+
error_vid: RegionVid,
2636+
) {
2637+
// Find the code to blame for the fact that `longer_fr` outlives `error_fr`.
2638+
let cause = self
2639+
.regioncx
2640+
.best_blame_constraint(
2641+
longer_fr,
2642+
NllRegionVariableOrigin::Placeholder(placeholder),
2643+
error_vid,
2644+
)
2645+
.0
2646+
.cause;
2647+
2648+
// FIXME these methods should have better names, and also probably not be this generic.
2649+
// FIXME note that we *throw away* the error element here! We probably want to
2650+
// thread it through the computation further down and use it, but there currently isn't
2651+
// anything there to receive it.
2652+
self.regioncx.universe_info(placeholder.universe).report_erroneous_element(
2653+
self,
2654+
placeholder,
2655+
None,
2656+
cause,
2657+
);
2658+
}
26282659
}
26292660

26302661
/// The degree of overlap between 2 places for borrow-checking.

0 commit comments

Comments
 (0)