Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework name_regions to not rely on reverse scc graph for non-member-constrain usages #137102

Merged
merged 1 commit into from
Feb 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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),
);
Expand All @@ -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 {
Expand Down Expand Up @@ -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(),
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one stays living in regioncx bc it's paired with its partner function above.

where
T: TypeFoldable<TyCtxt<'tcx>>,
{
Expand Down
13 changes: 13 additions & 0 deletions tests/ui/borrowck/alias-liveness/name-region.rs
Original file line number Diff line number Diff line change
@@ -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() {}
14 changes: 14 additions & 0 deletions tests/ui/borrowck/alias-liveness/name-region.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Loading