From 921007f644e8caa026190c5ab27316f1cd62758d Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Fri, 8 Sep 2023 09:50:00 +0300 Subject: [PATCH] wip2 --- .../src/infer/error_reporting/mod.rs | 39 +++++++------------ compiler/rustc_middle/src/ty/context.rs | 27 ++++++++----- 2 files changed, 31 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 5feee0dd02669..b126e2a0adeb7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2318,11 +2318,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .emit(); } - pub fn name_region( - &self, - generic_param_scope: LocalDefId, - lifetime: Region<'tcx>, - ) -> Option<(String, Vec<(Span, String)>)> { + pub fn name_region(&self, lifetime: Region<'tcx>) -> Option<(String, Vec<(Span, String)>)> { struct LifetimeVisitor<'tcx, 'a> { tcx: TyCtxt<'tcx>, needle: hir::LifetimeName, @@ -2368,34 +2364,26 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - let mut lifetime = lifetime; - let (lifetime_def_id, lifetime_scope) = loop { - let (def_id, scope) = match lifetime.kind() { - ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, .. }) - | ty::ReFree(ty::FreeRegion { bound_region: ty::BrNamed(def_id, _), .. }) - if !lifetime.has_name() => - { - (def_id.expect_local(), self.tcx.local_parent(def_id)) - } - _ => return None, - }; - if self.tcx.def_kind(scope) != DefKind::OpaqueTy { - break (def_id, scope); + let (lifetime_def_id, lifetime_scope) = match self.tcx.is_suitable_region(lifetime)? { + ty::FreeRegionInfo { def_id, boundregion: ty::BrNamed(lt_def_id, _), .. } + if lifetime.has_name() => + { + (lt_def_id.expect_local(), def_id) } - lifetime = self.tcx.map_rpit_lifetime_to_fn_lifetime(def_id); + _ => return None, }; let mut add_lt_suggs = vec![]; let new_lt = { - let generics = self.tcx.generics_of(generic_param_scope); + let generics = self.tcx.generics_of(lifetime_scope); let mut used_names = iter::successors(Some(generics), |g| g.parent.map(|p| self.tcx.generics_of(p))) .flat_map(|g| &g.params) .filter(|p| matches!(p.kind, ty::GenericParamDefKind::Lifetime)) .map(|p| p.name) .collect::>(); - if let Some(hir_id) = self.tcx.opt_local_def_id_to_hir_id(generic_param_scope) { + if let Some(hir_id) = self.tcx.opt_local_def_id_to_hir_id(lifetime_scope) { // consider late-bound lifetimes ... used_names.extend(self.tcx.late_bound_vars(hir_id).into_iter().filter_map(|p| { match p { @@ -2450,9 +2438,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let generics = self.tcx.generics_of(generic_param_scope); // type_param_span is (span, has_bounds) let type_param_span = match bound_kind { + // Account for the case where `param` corresponds to `Self`, + // which doesn't have the expected type argument. GenericKind::Param(ref param) if !(generics.has_self && param.index == 0) => { - // Account for the case where `param` corresponds to `Self`, - // which doesn't have the expected type argument. let type_param = generics.type_param(param, self.tcx); let def_id = type_param.def_id.expect_local(); // Get the `hir::Param` to verify whether it already has any bounds. @@ -2609,9 +2597,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { "...", None, ); - let (new_lt, add_lt_suggs) = self - .name_region(generic_param_scope, sub) - .unwrap_or_else(|| (format!("{sub}"), vec![])); + let (new_lt, add_lt_suggs) = + self.name_region(sub).unwrap_or_else(|| (format!("{sub}"), vec![])); binding_suggestion(&mut err, type_param_span, bound_kind, new_lt, add_lt_suggs); err } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a484b4af13bec..916455a07c466 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1052,16 +1052,25 @@ impl<'tcx> TyCtxt<'tcx> { } /// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region. - pub fn is_suitable_region(self, region: Region<'tcx>) -> Option { - let (suitable_region_binding_scope, bound_region) = match *region { - ty::ReFree(ref free_region) => { - (free_region.scope.expect_local(), free_region.bound_region) + pub fn is_suitable_region(self, mut region: Region<'tcx>) -> Option { + let (suitable_region_binding_scope, bound_region) = loop { + let (scope, bound_region) = match *region { + ty::ReFree(ref free_region) => { + (free_region.scope.expect_local(), free_region.bound_region) + } + ty::ReEarlyBound(ref ebr) => ( + self.local_parent(ebr.def_id.expect_local()), + ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name), + ), + _ => return None, // not a free region + }; + if let (DefKind::OpaqueTy, ty::BrNamed(def_id, _)) = + (self.def_kind(scope), bound_region) + { + region = self.map_rpit_lifetime_to_fn_lifetime(def_id.expect_local()); + continue; } - ty::ReEarlyBound(ref ebr) => ( - self.local_parent(ebr.def_id.expect_local()), - ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name), - ), - _ => return None, // not a free region + break (scope, bound_region); }; let is_impl_item = match self.hir().find_by_def_id(suitable_region_binding_scope) {