Skip to content

Commit d4be95f

Browse files
committed
Improved fully elaborated type generation to replace '_#2r-style regions.
1 parent 53dda8e commit d4be95f

File tree

2 files changed

+39
-13
lines changed

2 files changed

+39
-13
lines changed

src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
321321
debug!("report_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}",
322322
fr_is_local, outlived_fr_is_local, category);
323323

324-
match (fr_is_local, outlived_fr_is_local) {
325-
(true, false) =>
324+
match (category, fr_is_local, outlived_fr_is_local) {
325+
(ConstraintCategory::Assignment, true, false) |
326+
(ConstraintCategory::CallArgument, true, false) =>
326327
self.report_escapes_closure_error(mir, infcx, mir_def_id, fr, outlived_fr,
327328
category, span, errors_buffer),
328329
_ =>

src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
146146
self.universal_regions.unnormalized_input_tys[implicit_inputs + argument_index];
147147
if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument(
148148
infcx,
149+
mir,
149150
mir_def_id,
150151
fr,
151152
arg_ty,
@@ -172,6 +173,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
172173
fn give_name_if_we_can_match_hir_ty_from_argument(
173174
&self,
174175
infcx: &InferCtxt<'_, '_, 'tcx>,
176+
mir: &Mir<'tcx>,
175177
mir_def_id: DefId,
176178
needle_fr: RegionVid,
177179
argument_ty: Ty<'tcx>,
@@ -188,8 +190,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
188190
// must highlight the variable.
189191
hir::TyKind::Infer => self.give_name_if_we_cannot_match_hir_ty(
190192
infcx,
193+
mir,
194+
needle_fr,
191195
argument_ty,
192-
argument_hir_ty,
193196
counter,
194197
diag,
195198
),
@@ -219,24 +222,46 @@ impl<'tcx> RegionInferenceContext<'tcx> {
219222
fn give_name_if_we_cannot_match_hir_ty(
220223
&self,
221224
infcx: &InferCtxt<'_, '_, 'tcx>,
225+
mir: &Mir<'tcx>,
226+
needle_fr: RegionVid,
222227
argument_ty: Ty<'tcx>,
223-
argument_hir_ty: &hir::Ty,
224228
counter: &mut usize,
225229
diag: &mut DiagnosticBuilder<'_>,
226230
) -> Option<InternedString> {
227231
let mut type_name = infcx.extract_type_name(&argument_ty);
228-
229-
type_name.find("&").map(|index| {
232+
let argument_index = self.get_argument_index_for_region(infcx.tcx, needle_fr)?;
233+
let mut first_region_name = None;
234+
235+
debug!("give_name_if_we_cannot_match_hir_ty: type_name={:?}", type_name);
236+
while let Some(start_index) = type_name.find("&'_#") {
237+
if let Some(end_index) = type_name[start_index..].find(' ') {
238+
// Need to make the `end_index` relative to the full string.
239+
let end_index = start_index + end_index;
240+
// `start_index + 1` skips the `&`.
241+
// `end_index` goes until the space after the region.
242+
type_name.replace_range(start_index + 1..end_index, "");
243+
}
244+
}
245+
debug!("give_name_if_we_cannot_match_hir_ty: type_name={:?}", type_name);
246+
247+
let mut index = 0;
248+
while let Some(next_index) = type_name[index..].find("&") {
249+
// At this point, next_index is the index of the `&` character (starting from
250+
// the last `&` character).
251+
debug!("give_name_if_we_cannot_match_hir_ty: start-of-loop index={:?} type_name={:?}",
252+
index, type_name);
230253
let region_name = self.synthesize_region_name(counter).as_str();
231-
type_name.insert_str(index + 1, &format!("{} ", region_name));
254+
if first_region_name.is_none() { first_region_name = Some(region_name); }
255+
256+
// Compute the index of the character after `&` in the original string.
257+
index = next_index + index + 1;
258+
type_name.insert_str(index, &format!("{}", region_name));
259+
}
232260

233-
diag.span_label(
234-
argument_hir_ty.span,
235-
format!("has type `{}`", type_name),
236-
);
261+
let (_, span) = self.get_argument_name_and_span_for_region(mir, argument_index);
262+
diag.span_label(span, format!("has type `{}`", type_name));
237263

238-
region_name.as_interned_str()
239-
})
264+
first_region_name.map(|s| s.as_interned_str())
240265
}
241266

242267
/// Attempts to highlight the specific part of a type annotation

0 commit comments

Comments
 (0)