Skip to content

Commit 2dc9304

Browse files
Auto merge of #142623 - amandasystems:early-placeholder-errors, r=<try>
Move placeholder error handling to before region inference
2 parents 0bbef55 + 603b548 commit 2dc9304

File tree

14 files changed

+410
-494
lines changed

14 files changed

+410
-494
lines changed

compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs

Lines changed: 15 additions & 12 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 {
@@ -153,10 +153,17 @@ pub(crate) trait TypeOpInfo<'tcx> {
153153
&self,
154154
mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
155155
placeholder: ty::PlaceholderRegion,
156-
error_element: RegionElement,
156+
error_element: Option<ty::PlaceholderRegion>,
157157
cause: ObligationCause<'tcx>,
158158
) {
159159
let tcx = mbcx.infcx.tcx;
160+
161+
// FIXME: this logic is convoluted and strange, and
162+
// we should probably just use the placeholders we get
163+
// as arguments! However, upstream error reporting code
164+
// needs adaptations for that to work (this universe is
165+
// neither the assigned one, nor the calculated one but
166+
// some base-shifted one for some reason?).
160167
let base_universe = self.base_universe();
161168
debug!(?base_universe);
162169

@@ -172,20 +179,16 @@ pub(crate) trait TypeOpInfo<'tcx> {
172179
ty::Placeholder { universe: adjusted_universe.into(), bound: placeholder.bound },
173180
);
174181

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());
182+
// FIXME: one day this should just be error_element, but see above about the adjusted universes. At that point, this method can probably be removed entirely.
183+
let error_region = error_element.and_then(|e| {
184+
let adjusted_universe = e.universe.as_u32().checked_sub(base_universe.as_u32());
180185
adjusted_universe.map(|adjusted| {
181186
ty::Region::new_placeholder(
182187
tcx,
183-
ty::Placeholder { universe: adjusted.into(), bound: error_placeholder.bound },
188+
ty::Placeholder { universe: adjusted.into(), bound: e.bound },
184189
)
185190
})
186-
} else {
187-
None
188-
};
191+
});
189192

190193
debug!(?placeholder_region);
191194

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

Lines changed: 41 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,18 @@ pub(crate) enum RegionErrorKind<'tcx> {
104104
/// A generic bound failure for a type test (`T: 'a`).
105105
TypeTestError { type_test: TypeTest<'tcx> },
106106

107-
/// Higher-ranked subtyping error.
108-
BoundUniversalRegionError {
107+
/// 'a outlives 'b, which does not hold. 'a is always a
108+
/// placeholder and 'b is either an existential that cannot name
109+
/// 'a, or another placeholder.
110+
PlaceholderOutlivesIllegalRegion { longer_fr: RegionVid, illegally_outlived_r: RegionVid },
111+
112+
/// Higher-ranked subtyping error. A placeholder outlives
113+
/// either a location or a universal region.
114+
PlaceholderOutlivesLocationOrUniversal {
109115
/// The placeholder free region.
110116
longer_fr: RegionVid,
111117
/// The region element that erroneously must be outlived by `longer_fr`.
112118
error_element: RegionElement,
113-
/// The placeholder region.
114-
placeholder: ty::PlaceholderRegion,
115119
},
116120

117121
/// Any other lifetime error.
@@ -201,64 +205,38 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
201205
&self,
202206
diag: &mut Diag<'_>,
203207
lower_bound: RegionVid,
204-
) {
208+
) -> Option<()> {
205209
let tcx = self.infcx.tcx;
206210

207211
// find generic associated types in the given region 'lower_bound'
208-
let gat_id_and_generics = self
209-
.regioncx
210-
.placeholders_contained_in(lower_bound)
211-
.map(|placeholder| {
212-
if let Some(id) = placeholder.bound.kind.get_id()
213-
&& let Some(placeholder_id) = id.as_local()
214-
&& let gat_hir_id = tcx.local_def_id_to_hir_id(placeholder_id)
215-
&& let Some(generics_impl) =
216-
tcx.parent_hir_node(tcx.parent_hir_id(gat_hir_id)).generics()
217-
{
218-
Some((gat_hir_id, generics_impl))
219-
} else {
220-
None
221-
}
222-
})
223-
.collect::<Vec<_>>();
224-
debug!(?gat_id_and_generics);
212+
let scc = self.regioncx.constraint_sccs().scc(lower_bound);
213+
let placeholder: ty::PlaceholderRegion = self.regioncx.placeholder_representative(scc)?;
214+
let placeholder_id = placeholder.bound.kind.get_id()?.as_local()?;
215+
let gat_hir_id = self.infcx.tcx.local_def_id_to_hir_id(placeholder_id);
216+
let generics_impl =
217+
self.infcx.tcx.parent_hir_node(self.infcx.tcx.parent_hir_id(gat_hir_id)).generics()?;
225218

226219
// Look for the where-bound which introduces the placeholder.
227220
// As we're using the HIR, we need to handle both `for<'a> T: Trait<'a>`
228221
// and `T: for<'a> Trait`<'a>.
229222
let mut hrtb_bounds = vec![];
230-
gat_id_and_generics.iter().flatten().for_each(|&(gat_hir_id, generics)| {
231-
for pred in generics.predicates {
232-
let BoundPredicate(WhereBoundPredicate { bound_generic_params, bounds, .. }) =
233-
pred.kind
234-
else {
235-
continue;
236-
};
237-
if bound_generic_params
238-
.iter()
239-
.rfind(|bgp| tcx.local_def_id_to_hir_id(bgp.def_id) == gat_hir_id)
240-
.is_some()
241-
{
242-
for bound in *bounds {
243-
hrtb_bounds.push(bound);
244-
}
245-
} else {
246-
for bound in *bounds {
247-
if let Trait(trait_bound) = bound {
248-
if trait_bound
249-
.bound_generic_params
250-
.iter()
251-
.rfind(|bgp| tcx.local_def_id_to_hir_id(bgp.def_id) == gat_hir_id)
252-
.is_some()
253-
{
254-
hrtb_bounds.push(bound);
255-
return;
256-
}
257-
}
258-
}
223+
224+
for pred in generics_impl.predicates {
225+
let BoundPredicate(WhereBoundPredicate { bound_generic_params, bounds, .. }) =
226+
pred.kind
227+
else {
228+
continue;
229+
};
230+
if bound_generic_params
231+
.iter()
232+
.rfind(|bgp| self.infcx.tcx.local_def_id_to_hir_id(bgp.def_id) == gat_hir_id)
233+
.is_some()
234+
{
235+
for bound in *bounds {
236+
hrtb_bounds.push(bound);
259237
}
260238
}
261-
});
239+
}
262240
debug!(?hrtb_bounds);
263241

264242
let mut suggestions = vec![];
@@ -304,6 +282,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
304282
Applicability::MaybeIncorrect,
305283
);
306284
}
285+
Some(())
307286
}
308287

309288
/// Produces nice borrowck error diagnostics for all the errors collected in `nll_errors`.
@@ -361,28 +340,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
361340
}
362341
}
363342

364-
RegionErrorKind::BoundUniversalRegionError {
343+
RegionErrorKind::PlaceholderOutlivesLocationOrUniversal {
365344
longer_fr,
366-
placeholder,
367345
error_element,
368-
} => {
369-
let error_vid = self.regioncx.region_from_element(longer_fr, &error_element);
370-
371-
// Find the code to blame for the fact that `longer_fr` outlives `error_fr`.
372-
let cause = self
373-
.regioncx
374-
.best_blame_constraint(
375-
longer_fr,
376-
NllRegionVariableOrigin::Placeholder(placeholder),
377-
error_vid,
378-
)
379-
.0
380-
.cause;
381-
382-
let universe = placeholder.universe;
383-
let universe_info = self.regioncx.universe_info(universe);
346+
} => self.report_erroneous_rvid_reaches_placeholder(
347+
longer_fr,
348+
self.regioncx.region_from_element(longer_fr, &error_element),
349+
),
384350

385-
universe_info.report_erroneous_element(self, placeholder, error_element, cause);
351+
RegionErrorKind::PlaceholderOutlivesIllegalRegion {
352+
longer_fr,
353+
illegally_outlived_r,
354+
} => {
355+
self.report_erroneous_rvid_reaches_placeholder(longer_fr, illegally_outlived_r)
386356
}
387357

388358
RegionErrorKind::RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => {

0 commit comments

Comments
 (0)