]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_borrowck/src/diagnostics/region_name.rs
New upstream version 1.66.0+dfsg1
[rustc.git] / compiler / rustc_borrowck / src / diagnostics / region_name.rs
index 6c1eaa809c9055b65ce8e2892ee5dcf0d3981572..c044dbaba47e2faab5170228d73bd7c571302c0d 100644 (file)
@@ -251,7 +251,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
             .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr))
             .or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr))
             .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr))
-            .or_else(|| self.give_name_if_anonymous_region_appears_in_impl_signature(fr));
+            .or_else(|| self.give_name_if_anonymous_region_appears_in_impl_signature(fr))
+            .or_else(|| self.give_name_if_anonymous_region_appears_in_arg_position_impl_trait(fr));
 
         if let Some(ref value) = value {
             self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone());
@@ -707,7 +708,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                         hir::AsyncGeneratorKind::Block => " of async block",
                         hir::AsyncGeneratorKind::Closure => " of async closure",
                         hir::AsyncGeneratorKind::Fn => {
-                            let parent_item = hir.get_by_def_id(hir.get_parent_item(mir_hir_id));
+                            let parent_item =
+                                hir.get_by_def_id(hir.get_parent_item(mir_hir_id).def_id);
                             let output = &parent_item
                                 .fn_decl()
                                 .expect("generator lowered from async fn should be in fn")
@@ -863,20 +865,13 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
         };
 
         let tcx = self.infcx.tcx;
-        let body_parent_did = tcx.opt_parent(self.mir_def_id().to_def_id())?;
-        if tcx.parent(region.def_id) != body_parent_did
-            || tcx.def_kind(body_parent_did) != DefKind::Impl
-        {
+        let region_parent = tcx.parent(region.def_id);
+        if tcx.def_kind(region_parent) != DefKind::Impl {
             return None;
         }
 
-        let mut found = false;
-        tcx.fold_regions(tcx.type_of(body_parent_did), |r: ty::Region<'tcx>, _| {
-            if *r == ty::ReEarlyBound(region) {
-                found = true;
-            }
-            r
-        });
+        let found = tcx
+            .any_free_region_meets(&tcx.type_of(region_parent), |r| *r == ty::ReEarlyBound(region));
 
         Some(RegionName {
             name: self.synthesize_region_name(),
@@ -889,4 +884,92 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
             ),
         })
     }
+
+    fn give_name_if_anonymous_region_appears_in_arg_position_impl_trait(
+        &self,
+        fr: RegionVid,
+    ) -> Option<RegionName> {
+        let ty::ReEarlyBound(region) = *self.to_error_region(fr)? else {
+            return None;
+        };
+        if region.has_name() {
+            return None;
+        };
+
+        let predicates = self
+            .infcx
+            .tcx
+            .predicates_of(self.body.source.def_id())
+            .instantiate_identity(self.infcx.tcx)
+            .predicates;
+
+        if let Some(upvar_index) = self
+            .regioncx
+            .universal_regions()
+            .defining_ty
+            .upvar_tys()
+            .position(|ty| self.any_param_predicate_mentions(&predicates, ty, region))
+        {
+            let (upvar_name, upvar_span) = self.regioncx.get_upvar_name_and_span_for_region(
+                self.infcx.tcx,
+                &self.upvars,
+                upvar_index,
+            );
+            let region_name = self.synthesize_region_name();
+
+            Some(RegionName {
+                name: region_name,
+                source: RegionNameSource::AnonRegionFromUpvar(upvar_span, upvar_name),
+            })
+        } else if let Some(arg_index) = self
+            .regioncx
+            .universal_regions()
+            .unnormalized_input_tys
+            .iter()
+            .position(|ty| self.any_param_predicate_mentions(&predicates, *ty, region))
+        {
+            let (arg_name, arg_span) = self.regioncx.get_argument_name_and_span_for_region(
+                self.body,
+                &self.local_names,
+                arg_index,
+            );
+            let region_name = self.synthesize_region_name();
+
+            Some(RegionName {
+                name: region_name,
+                source: RegionNameSource::AnonRegionFromArgument(
+                    RegionNameHighlight::CannotMatchHirTy(arg_span, arg_name?.to_string()),
+                ),
+            })
+        } else {
+            None
+        }
+    }
+
+    fn any_param_predicate_mentions(
+        &self,
+        predicates: &[ty::Predicate<'tcx>],
+        ty: Ty<'tcx>,
+        region: ty::EarlyBoundRegion,
+    ) -> bool {
+        let tcx = self.infcx.tcx;
+        ty.walk().any(|arg| {
+            if let ty::GenericArgKind::Type(ty) = arg.unpack()
+                && let ty::Param(_) = ty.kind()
+            {
+                predicates.iter().any(|pred| {
+                    match pred.kind().skip_binder() {
+                        ty::PredicateKind::Trait(data) if data.self_ty() == ty => {}
+                        ty::PredicateKind::Projection(data) if data.projection_ty.self_ty() == ty => {}
+                        _ => return false,
+                    }
+                    tcx.any_free_region_meets(pred, |r| {
+                        *r == ty::ReEarlyBound(region)
+                    })
+                })
+            } else {
+                false
+            }
+        })
+    }
 }