about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2025-02-16 17:14:05 +0100
committerGitHub <noreply@github.com>2025-02-16 17:14:05 +0100
commitea9c8d9c1736a2e9c40b453a81fe4da552391143 (patch)
treeba4e0f9da972d93bc166fce53aa9d2e7442ff24a
parentfc094a1813de0fb58cb9d4be00f5e86701000f2a (diff)
parent17071ff8a5bef6e0f801e7d6b73529d0e1053b81 (diff)
downloadrust-ea9c8d9c1736a2e9c40b453a81fe4da552391143.tar.gz
rust-ea9c8d9c1736a2e9c40b453a81fe4da552391143.zip
Rollup merge of #137102 - compiler-errors:name_regions2, r=oli-obk
Rework `name_regions` to not rely on reverse scc graph for non-member-constrain usages

Fixes https://github.com/rust-lang/rust/issues/137015

Splits the `name_regions` into two versions: One meant for member region constraint error reporting (which I've renamed to `name_regions_for_member_constraint`), and one meant *just* to replace region vids with an external region.

Use the latter in the usage sites I added in #136559, since the regions returned by `name_regions_for_member_constraint` are also not *totally* accurate (which is fine for how they're used for member region constraint error reporting -- they're intentionally returning overapproximated universal regions so that we have something to name in `+ use<'a>` suggestions, because opaques can only capture universal regions and since member region constraints don't insert any edges into the region graph, the error region is probably gonna be shorter than a universal region) and because that function requires the reverse scc graph to have been computed which isn't done for our usages in #136559.
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs30
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs8
-rw-r--r--tests/ui/borrowck/alias-liveness/name-region.rs13
-rw-r--r--tests/ui/borrowck/alias-liveness/name-region.stderr14
4 files changed, 58 insertions, 7 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index b7e2510e035..df79da76bce 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -14,7 +14,10 @@ use rustc_infer::infer::{NllRegionVariableOrigin, RelateParamBound};
 use rustc_middle::bug;
 use rustc_middle::hir::place::PlaceBase;
 use rustc_middle::mir::{AnnotationSource, ConstraintCategory, ReturnConstraint};
-use rustc_middle::ty::{self, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeVisitor};
+use rustc_middle::ty::fold::fold_regions;
+use rustc_middle::ty::{
+    self, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitor,
+};
 use rustc_span::{Ident, Span, kw};
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
 use rustc_trait_selection::error_reporting::infer::nice_region_error::{
@@ -183,6 +186,17 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         }
     }
 
+    /// Map the regions in the type to named regions, where possible.
+    fn name_regions<T>(&self, tcx: TyCtxt<'tcx>, ty: T) -> T
+    where
+        T: TypeFoldable<TyCtxt<'tcx>>,
+    {
+        fold_regions(tcx, ty, |region, _| match *region {
+            ty::ReVar(vid) => self.to_error_region(vid).unwrap_or(region),
+            _ => region,
+        })
+    }
+
     /// Returns `true` if a closure is inferred to be an `FnMut` closure.
     fn is_closure_fn_mut(&self, fr: RegionVid) -> bool {
         if let Some(ty::ReLateParam(late_param)) = self.to_error_region(fr).as_deref()
@@ -314,7 +328,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                     let type_test_span = type_test.span;
 
                     if let Some(lower_bound_region) = lower_bound_region {
-                        let generic_ty = self.regioncx.name_regions(
+                        let generic_ty = self.name_regions(
                             self.infcx.tcx,
                             type_test.generic_kind.to_ty(self.infcx.tcx),
                         );
@@ -323,7 +337,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                             self.body.source.def_id().expect_local(),
                             type_test_span,
                             Some(origin),
-                            self.regioncx.name_regions(self.infcx.tcx, type_test.generic_kind),
+                            self.name_regions(self.infcx.tcx, type_test.generic_kind),
                             lower_bound_region,
                         ));
                     } else {
@@ -354,9 +368,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 }
 
                 RegionErrorKind::UnexpectedHiddenRegion { span, hidden_ty, key, member_region } => {
-                    let named_ty = self.regioncx.name_regions(self.infcx.tcx, hidden_ty);
-                    let named_key = self.regioncx.name_regions(self.infcx.tcx, key);
-                    let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region);
+                    let named_ty =
+                        self.regioncx.name_regions_for_member_constraint(self.infcx.tcx, hidden_ty);
+                    let named_key =
+                        self.regioncx.name_regions_for_member_constraint(self.infcx.tcx, key);
+                    let named_region = self
+                        .regioncx
+                        .name_regions_for_member_constraint(self.infcx.tcx, member_region);
                     let diag = unexpected_hidden_region_diagnostic(
                         self.infcx,
                         self.mir_def_id(),
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 9c19f8b3ad8..54f9e82dbb8 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -204,7 +204,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// that the regions produced are in fact equal to the named region they are
     /// replaced with. This is fine because this function is only to improve the
     /// region names in error messages.
-    pub(crate) fn name_regions<T>(&self, tcx: TyCtxt<'tcx>, ty: T) -> T
+    ///
+    /// This differs from `MirBorrowckCtxt::name_regions` since it is particularly
+    /// lax with mapping region vids that are *shorter* than a universal region to
+    /// that universal region. This is useful for member region constraints since
+    /// we want to suggest a universal region name to capture even if it's technically
+    /// not equal to the error region.
+    pub(crate) fn name_regions_for_member_constraint<T>(&self, tcx: TyCtxt<'tcx>, ty: T) -> T
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
diff --git a/tests/ui/borrowck/alias-liveness/name-region.rs b/tests/ui/borrowck/alias-liveness/name-region.rs
new file mode 100644
index 00000000000..9545a9eed2f
--- /dev/null
+++ b/tests/ui/borrowck/alias-liveness/name-region.rs
@@ -0,0 +1,13 @@
+// Make sure we don't ICE when trying to name the regions that appear in the alias
+// of the type test error.
+
+trait AnotherTrait {
+    type Ty2<'a>;
+}
+
+fn test_alias<T: AnotherTrait>(_: &'static T::Ty2<'_>) {
+    let _: &'static T::Ty2<'_>;
+    //~^ ERROR the associated type `<T as AnotherTrait>::Ty2<'_>` may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/borrowck/alias-liveness/name-region.stderr b/tests/ui/borrowck/alias-liveness/name-region.stderr
new file mode 100644
index 00000000000..9a5dd711c68
--- /dev/null
+++ b/tests/ui/borrowck/alias-liveness/name-region.stderr
@@ -0,0 +1,14 @@
+error[E0310]: the associated type `<T as AnotherTrait>::Ty2<'_>` may not live long enough
+  --> $DIR/name-region.rs:9:12
+   |
+LL |     let _: &'static T::Ty2<'_>;
+   |            ^^^^^^^^^^^^^^^^^^^
+   |            |
+   |            the associated type `<T as AnotherTrait>::Ty2<'_>` must be valid for the static lifetime...
+   |            ...so that the type `<T as AnotherTrait>::Ty2<'_>` will meet its required lifetime bounds
+   |
+   = help: consider adding an explicit lifetime bound `<T as AnotherTrait>::Ty2<'_>: 'static`...
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0310`.