From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- .../rustc_borrowck/src/diagnostics/var_name.rs | 133 +++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 compiler/rustc_borrowck/src/diagnostics/var_name.rs (limited to 'compiler/rustc_borrowck/src/diagnostics/var_name.rs') diff --git a/compiler/rustc_borrowck/src/diagnostics/var_name.rs b/compiler/rustc_borrowck/src/diagnostics/var_name.rs new file mode 100644 index 000000000..9ba29f04b --- /dev/null +++ b/compiler/rustc_borrowck/src/diagnostics/var_name.rs @@ -0,0 +1,133 @@ +use crate::Upvar; +use crate::{nll::ToRegionVid, region_infer::RegionInferenceContext}; +use rustc_index::vec::{Idx, IndexVec}; +use rustc_middle::mir::{Body, Local}; +use rustc_middle::ty::{RegionVid, TyCtxt}; +use rustc_span::source_map::Span; +use rustc_span::symbol::Symbol; + +impl<'tcx> RegionInferenceContext<'tcx> { + pub(crate) fn get_var_name_and_span_for_region( + &self, + tcx: TyCtxt<'tcx>, + body: &Body<'tcx>, + local_names: &IndexVec>, + upvars: &[Upvar<'tcx>], + fr: RegionVid, + ) -> Option<(Option, Span)> { + debug!("get_var_name_and_span_for_region(fr={:?})", fr); + assert!(self.universal_regions().is_universal_region(fr)); + + debug!("get_var_name_and_span_for_region: attempting upvar"); + self.get_upvar_index_for_region(tcx, fr) + .map(|index| { + // FIXME(project-rfc-2229#8): Use place span for diagnostics + let (name, span) = self.get_upvar_name_and_span_for_region(tcx, upvars, index); + (Some(name), span) + }) + .or_else(|| { + debug!("get_var_name_and_span_for_region: attempting argument"); + self.get_argument_index_for_region(tcx, fr).map(|index| { + self.get_argument_name_and_span_for_region(body, local_names, index) + }) + }) + } + + /// Search the upvars (if any) to find one that references fr. Return its index. + pub(crate) fn get_upvar_index_for_region( + &self, + tcx: TyCtxt<'tcx>, + fr: RegionVid, + ) -> Option { + let upvar_index = + self.universal_regions().defining_ty.upvar_tys().position(|upvar_ty| { + debug!("get_upvar_index_for_region: upvar_ty={:?}", upvar_ty); + tcx.any_free_region_meets(&upvar_ty, |r| { + let r = r.to_region_vid(); + debug!("get_upvar_index_for_region: r={:?} fr={:?}", r, fr); + r == fr + }) + })?; + + let upvar_ty = self.universal_regions().defining_ty.upvar_tys().nth(upvar_index); + + debug!( + "get_upvar_index_for_region: found {:?} in upvar {} which has type {:?}", + fr, upvar_index, upvar_ty, + ); + + Some(upvar_index) + } + + /// Given the index of an upvar, finds its name and the span from where it was + /// declared. + pub(crate) fn get_upvar_name_and_span_for_region( + &self, + tcx: TyCtxt<'tcx>, + upvars: &[Upvar<'tcx>], + upvar_index: usize, + ) -> (Symbol, Span) { + let upvar_hir_id = upvars[upvar_index].place.get_root_variable(); + debug!("get_upvar_name_and_span_for_region: upvar_hir_id={:?}", upvar_hir_id); + + let upvar_name = tcx.hir().name(upvar_hir_id); + let upvar_span = tcx.hir().span(upvar_hir_id); + debug!( + "get_upvar_name_and_span_for_region: upvar_name={:?} upvar_span={:?}", + upvar_name, upvar_span + ); + + (upvar_name, upvar_span) + } + + /// Search the argument types for one that references fr (which should be a free region). + /// Returns Some(_) with the index of the input if one is found. + /// + /// N.B., in the case of a closure, the index is indexing into the signature as seen by the + /// user - in particular, index 0 is not the implicit self parameter. + pub(crate) fn get_argument_index_for_region( + &self, + tcx: TyCtxt<'tcx>, + fr: RegionVid, + ) -> Option { + let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs(); + let argument_index = + self.universal_regions().unnormalized_input_tys.iter().skip(implicit_inputs).position( + |arg_ty| { + debug!("get_argument_index_for_region: arg_ty = {:?}", arg_ty); + tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr) + }, + )?; + + debug!( + "get_argument_index_for_region: found {:?} in argument {} which has type {:?}", + fr, + argument_index, + self.universal_regions().unnormalized_input_tys[argument_index], + ); + + Some(argument_index) + } + + /// Given the index of an argument, finds its name (if any) and the span from where it was + /// declared. + pub(crate) fn get_argument_name_and_span_for_region( + &self, + body: &Body<'tcx>, + local_names: &IndexVec>, + argument_index: usize, + ) -> (Option, Span) { + let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs(); + let argument_local = Local::new(implicit_inputs + argument_index + 1); + debug!("get_argument_name_and_span_for_region: argument_local={:?}", argument_local); + + let argument_name = local_names[argument_local]; + let argument_span = body.local_decls[argument_local].source_info.span; + debug!( + "get_argument_name_and_span_for_region: argument_name={:?} argument_span={:?}", + argument_name, argument_span + ); + + (argument_name, argument_span) + } +} -- cgit v1.2.3