diff options
| author | David Wood <david@davidtw.co> | 2018-07-23 16:26:33 +0200 |
|---|---|---|
| committer | David Wood <david@davidtw.co> | 2018-07-27 11:18:11 +0200 |
| commit | d4be95f0ffb46c752293c951eeebebdadd336180 (patch) | |
| tree | 5ee1fb98247a8401d7958ee4bbfe92b58d8d87bd | |
| parent | 53dda8e915e54bc65b41599738245d62dbe3e6df (diff) | |
| download | rust-d4be95f0ffb46c752293c951eeebebdadd336180.tar.gz rust-d4be95f0ffb46c752293c951eeebebdadd336180.zip | |
Improved fully elaborated type generation to replace `'_#2r`-style regions.
| -rw-r--r-- | src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs | 5 | ||||
| -rw-r--r-- | src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs | 47 |
2 files changed, 39 insertions, 13 deletions
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 7ba1e50cef3..cef6ab311a3 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -321,8 +321,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!("report_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}", fr_is_local, outlived_fr_is_local, category); - match (fr_is_local, outlived_fr_is_local) { - (true, false) => + match (category, fr_is_local, outlived_fr_is_local) { + (ConstraintCategory::Assignment, true, false) | + (ConstraintCategory::CallArgument, true, false) => self.report_escapes_closure_error(mir, infcx, mir_def_id, fr, outlived_fr, category, span, errors_buffer), _ => diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index 05ac130f000..6c400278b70 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -146,6 +146,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.universal_regions.unnormalized_input_tys[implicit_inputs + argument_index]; if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument( infcx, + mir, mir_def_id, fr, arg_ty, @@ -172,6 +173,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { fn give_name_if_we_can_match_hir_ty_from_argument( &self, infcx: &InferCtxt<'_, '_, 'tcx>, + mir: &Mir<'tcx>, mir_def_id: DefId, needle_fr: RegionVid, argument_ty: Ty<'tcx>, @@ -188,8 +190,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { // must highlight the variable. hir::TyKind::Infer => self.give_name_if_we_cannot_match_hir_ty( infcx, + mir, + needle_fr, argument_ty, - argument_hir_ty, counter, diag, ), @@ -219,24 +222,46 @@ impl<'tcx> RegionInferenceContext<'tcx> { fn give_name_if_we_cannot_match_hir_ty( &self, infcx: &InferCtxt<'_, '_, 'tcx>, + mir: &Mir<'tcx>, + needle_fr: RegionVid, argument_ty: Ty<'tcx>, - argument_hir_ty: &hir::Ty, counter: &mut usize, diag: &mut DiagnosticBuilder<'_>, ) -> Option<InternedString> { let mut type_name = infcx.extract_type_name(&argument_ty); - - type_name.find("&").map(|index| { + let argument_index = self.get_argument_index_for_region(infcx.tcx, needle_fr)?; + let mut first_region_name = None; + + debug!("give_name_if_we_cannot_match_hir_ty: type_name={:?}", type_name); + while let Some(start_index) = type_name.find("&'_#") { + if let Some(end_index) = type_name[start_index..].find(' ') { + // Need to make the `end_index` relative to the full string. + let end_index = start_index + end_index; + // `start_index + 1` skips the `&`. + // `end_index` goes until the space after the region. + type_name.replace_range(start_index + 1..end_index, ""); + } + } + debug!("give_name_if_we_cannot_match_hir_ty: type_name={:?}", type_name); + + let mut index = 0; + while let Some(next_index) = type_name[index..].find("&") { + // At this point, next_index is the index of the `&` character (starting from + // the last `&` character). + debug!("give_name_if_we_cannot_match_hir_ty: start-of-loop index={:?} type_name={:?}", + index, type_name); let region_name = self.synthesize_region_name(counter).as_str(); - type_name.insert_str(index + 1, &format!("{} ", region_name)); + if first_region_name.is_none() { first_region_name = Some(region_name); } + + // Compute the index of the character after `&` in the original string. + index = next_index + index + 1; + type_name.insert_str(index, &format!("{}", region_name)); + } - diag.span_label( - argument_hir_ty.span, - format!("has type `{}`", type_name), - ); + let (_, span) = self.get_argument_name_and_span_for_region(mir, argument_index); + diag.span_label(span, format!("has type `{}`", type_name)); - region_name.as_interned_str() - }) + first_region_name.map(|s| s.as_interned_str()) } /// Attempts to highlight the specific part of a type annotation |
