Skip to content

Commit

Permalink
small refactor to region error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed Dec 6, 2024
1 parent 17ed6ea commit 6f5bf6c
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 131 deletions.
24 changes: 13 additions & 11 deletions compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
return;
};

let fn_returns = self.infcx.tcx.return_type_impl_or_dyn_traits(suitable_region.def_id);
let fn_returns = self.infcx.tcx.return_type_impl_or_dyn_traits(suitable_region.scope);

let param = if let Some(param) =
find_param_with_region(self.infcx.tcx, self.mir_def_id(), f, outlived_f)
Expand All @@ -875,15 +875,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
Some(arg),
captures,
Some((param.param_ty_span, param.param_ty.to_string())),
Some(suitable_region.def_id),
Some(suitable_region.scope),
);
return;
}

let Some((alias_tys, alias_span, lt_addition_span)) = self
.infcx
.tcx
.return_type_impl_or_dyn_traits_with_type_alias(suitable_region.def_id)
.return_type_impl_or_dyn_traits_with_type_alias(suitable_region.scope)
else {
return;
};
Expand Down Expand Up @@ -1018,18 +1018,20 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
return;
};

let Some((ty_sub, _)) =
self.infcx.tcx.is_suitable_region(self.mir_def_id(), sub).and_then(|anon_reg| {
find_anon_type(self.infcx.tcx, self.mir_def_id(), sub, &anon_reg.bound_region)
})
let Some((ty_sub, _)) = self
.infcx
.tcx
.is_suitable_region(self.mir_def_id(), sub)
.and_then(|_| find_anon_type(self.infcx.tcx, self.mir_def_id(), sub))
else {
return;
};

let Some((ty_sup, _)) =
self.infcx.tcx.is_suitable_region(self.mir_def_id(), sup).and_then(|anon_reg| {
find_anon_type(self.infcx.tcx, self.mir_def_id(), sup, &anon_reg.bound_region)
})
let Some((ty_sup, _)) = self
.infcx
.tcx
.is_suitable_region(self.mir_def_id(), sup)
.and_then(|_| find_anon_type(self.infcx.tcx, self.mir_def_id(), sup))
else {
return;
};
Expand Down
17 changes: 7 additions & 10 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1115,10 +1115,10 @@ impl<'tcx> CommonConsts<'tcx> {
/// either a `ReEarlyParam` or `ReLateParam`.
#[derive(Debug)]
pub struct FreeRegionInfo {
/// `LocalDefId` of the free region.
pub def_id: LocalDefId,
/// the bound region corresponding to free region.
pub bound_region: ty::BoundRegionKind,
/// `LocalDefId` of the scope.
pub scope: LocalDefId,
/// the `DefId` of the free region.
pub region_def_id: DefId,
/// checks if bound region is in Impl Item
pub is_impl_item: bool,
}
Expand Down Expand Up @@ -1979,7 +1979,7 @@ impl<'tcx> TyCtxt<'tcx> {
generic_param_scope: LocalDefId,
mut region: Region<'tcx>,
) -> Option<FreeRegionInfo> {
let (suitable_region_binding_scope, bound_region) = loop {
let (suitable_region_binding_scope, region_def_id) = loop {
let def_id =
region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
let scope = self.local_parent(def_id);
Expand All @@ -1989,10 +1989,7 @@ impl<'tcx> TyCtxt<'tcx> {
region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
continue;
}
break (
scope,
ty::BoundRegionKind::Named(def_id.into(), self.item_name(def_id.into())),
);
break (scope, def_id.into());
};

let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
Expand All @@ -2001,7 +1998,7 @@ impl<'tcx> TyCtxt<'tcx> {
_ => false,
};

Some(FreeRegionInfo { def_id: suitable_region_binding_scope, bound_region, is_impl_item })
Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
}

/// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,26 +63,16 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
}

// Determine whether the sub and sup consist of both anonymous (elided) regions.
let anon_reg_sup = self.tcx().is_suitable_region(self.generic_param_scope, sup)?;
let sup_info = self.tcx().is_suitable_region(self.generic_param_scope, sup)?;

let anon_reg_sub = self.tcx().is_suitable_region(self.generic_param_scope, sub)?;
let scope_def_id_sup = anon_reg_sup.def_id;
let bregion_sup = anon_reg_sup.bound_region;
let scope_def_id_sub = anon_reg_sub.def_id;
let bregion_sub = anon_reg_sub.bound_region;
let sub_info = self.tcx().is_suitable_region(self.generic_param_scope, sub)?;

let ty_sup = find_anon_type(self.tcx(), self.generic_param_scope, sup, &bregion_sup)?;
let ty_sup = find_anon_type(self.tcx(), self.generic_param_scope, sup)?;

let ty_sub = find_anon_type(self.tcx(), self.generic_param_scope, sub, &bregion_sub)?;
let ty_sub = find_anon_type(self.tcx(), self.generic_param_scope, sub)?;

debug!(
"try_report_anon_anon_conflict: found_param1={:?} sup={:?} br1={:?}",
ty_sub, sup, bregion_sup
);
debug!(
"try_report_anon_anon_conflict: found_param2={:?} sub={:?} br2={:?}",
ty_sup, sub, bregion_sub
);
debug!("try_report_anon_anon_conflict: found_param1={:?} sup={:?}", ty_sub, sup);
debug!("try_report_anon_anon_conflict: found_param2={:?} sub={:?}", ty_sup, sub);

let (ty_sup, ty_fndecl_sup) = ty_sup;
let (ty_sub, ty_fndecl_sub) = ty_sub;
Expand All @@ -93,9 +83,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
self.find_param_with_region(sub, sub)?;

let sup_is_ret_type =
self.is_return_type_anon(scope_def_id_sup, bregion_sup, ty_fndecl_sup);
self.is_return_type_anon(sup_info.scope, sup_info.region_def_id, ty_fndecl_sup);
let sub_is_ret_type =
self.is_return_type_anon(scope_def_id_sub, bregion_sub, ty_fndecl_sub);
self.is_return_type_anon(sub_info.scope, sub_info.region_def_id, ty_fndecl_sub);

debug!(
"try_report_anon_anon_conflict: sub_is_ret_type={:?} sup_is_ret_type={:?}",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use core::ops::ControlFlow;

use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_middle::hir::map::Map;
use rustc_middle::hir::nested_filter;
Expand All @@ -28,16 +28,15 @@ pub fn find_anon_type<'tcx>(
tcx: TyCtxt<'tcx>,
generic_param_scope: LocalDefId,
region: Region<'tcx>,
br: &ty::BoundRegionKind,
) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnSig<'tcx>)> {
let anon_reg = tcx.is_suitable_region(generic_param_scope, region)?;
let fn_sig = tcx.hir_node_by_def_id(anon_reg.def_id).fn_sig()?;
let fn_sig = tcx.hir_node_by_def_id(anon_reg.scope).fn_sig()?;

fn_sig
.decl
.inputs
.iter()
.find_map(|arg| find_component_for_bound_region(tcx, arg, br))
.find_map(|arg| find_component_for_bound_region(tcx, arg, anon_reg.region_def_id))
.map(|ty| (ty, fn_sig))
}

Expand All @@ -46,9 +45,9 @@ pub fn find_anon_type<'tcx>(
fn find_component_for_bound_region<'tcx>(
tcx: TyCtxt<'tcx>,
arg: &'tcx hir::Ty<'tcx>,
br: &ty::BoundRegionKind,
region_def_id: DefId,
) -> Option<&'tcx hir::Ty<'tcx>> {
FindNestedTypeVisitor { tcx, bound_region: *br, current_index: ty::INNERMOST }
FindNestedTypeVisitor { tcx, region_def_id, current_index: ty::INNERMOST }
.visit_ty(arg)
.break_value()
}
Expand All @@ -62,9 +61,8 @@ fn find_component_for_bound_region<'tcx>(
// specific part of the type in the error message.
struct FindNestedTypeVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
// The bound_region corresponding to the Refree(freeregion)
// associated with the anonymous region we are looking for.
bound_region: ty::BoundRegionKind,
// The `DefId` of the region we're looking for.
region_def_id: DefId,
current_index: ty::DebruijnIndex,
}

Expand Down Expand Up @@ -96,48 +94,39 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
hir::TyKind::Ref(lifetime, _) => {
// the lifetime of the Ref
let hir_id = lifetime.hir_id;
match (self.tcx.named_bound_var(hir_id), self.bound_region) {
match self.tcx.named_bound_var(hir_id) {
// Find the index of the named region that was part of the
// error. We will then search the function parameters for a bound
// region at the right depth with the same index
(
Some(rbv::ResolvedArg::EarlyBound(id)),
ty::BoundRegionKind::Named(def_id, _),
) => {
debug!("EarlyBound id={:?} def_id={:?}", id, def_id);
if id.to_def_id() == def_id {
Some(rbv::ResolvedArg::EarlyBound(id)) => {
debug!("EarlyBound id={:?}", id);
if id.to_def_id() == self.region_def_id {
return ControlFlow::Break(arg);
}
}

// Find the index of the named region that was part of the
// error. We will then search the function parameters for a bound
// region at the right depth with the same index
(
Some(rbv::ResolvedArg::LateBound(debruijn_index, _, id)),
ty::BoundRegionKind::Named(def_id, _),
) => {
Some(rbv::ResolvedArg::LateBound(debruijn_index, _, id)) => {
debug!(
"FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}",
debruijn_index
);
debug!("LateBound id={:?} def_id={:?}", id, def_id);
if debruijn_index == self.current_index && id.to_def_id() == def_id {
debug!("LateBound id={:?}", id);
if debruijn_index == self.current_index
&& id.to_def_id() == self.region_def_id
{
return ControlFlow::Break(arg);
}
}

(
Some(
rbv::ResolvedArg::StaticLifetime
| rbv::ResolvedArg::Free(_, _)
| rbv::ResolvedArg::EarlyBound(_)
| rbv::ResolvedArg::LateBound(_, _, _)
| rbv::ResolvedArg::Error(_),
)
| None,
_,
) => {
Some(
rbv::ResolvedArg::StaticLifetime
| rbv::ResolvedArg::Free(_, _)
| rbv::ResolvedArg::Error(_),
)
| None => {
debug!("no arg found");
}
}
Expand All @@ -151,7 +140,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
return if intravisit::walk_ty(
&mut TyPathVisitor {
tcx: self.tcx,
bound_region: self.bound_region,
region_def_id: self.region_def_id,
current_index: self.current_index,
},
arg,
Expand Down Expand Up @@ -179,7 +168,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
// specific part of the type in the error message.
struct TyPathVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
bound_region: ty::BoundRegionKind,
region_def_id: DefId,
current_index: ty::DebruijnIndex,
}

Expand All @@ -192,38 +181,29 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
}

fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) -> Self::Result {
match (self.tcx.named_bound_var(lifetime.hir_id), self.bound_region) {
match self.tcx.named_bound_var(lifetime.hir_id) {
// the lifetime of the TyPath!
(Some(rbv::ResolvedArg::EarlyBound(id)), ty::BoundRegionKind::Named(def_id, _)) => {
debug!("EarlyBound id={:?} def_id={:?}", id, def_id);
if id.to_def_id() == def_id {
Some(rbv::ResolvedArg::EarlyBound(id)) => {
debug!("EarlyBound id={:?}", id);
if id.to_def_id() == self.region_def_id {
return ControlFlow::Break(());
}
}

(
Some(rbv::ResolvedArg::LateBound(debruijn_index, _, id)),
ty::BoundRegionKind::Named(def_id, _),
) => {
Some(rbv::ResolvedArg::LateBound(debruijn_index, _, id)) => {
debug!("FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}", debruijn_index,);
debug!("id={:?}", id);
debug!("def_id={:?}", def_id);
if debruijn_index == self.current_index && id.to_def_id() == def_id {
if debruijn_index == self.current_index && id.to_def_id() == self.region_def_id {
return ControlFlow::Break(());
}
}

(
Some(
rbv::ResolvedArg::StaticLifetime
| rbv::ResolvedArg::EarlyBound(_)
| rbv::ResolvedArg::LateBound(_, _, _)
| rbv::ResolvedArg::Free(_, _)
| rbv::ResolvedArg::Error(_),
)
| None,
_,
) => {
Some(
rbv::ResolvedArg::StaticLifetime
| rbv::ResolvedArg::Free(_, _)
| rbv::ResolvedArg::Error(_),
)
| None => {
debug!("no arg found");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let param = anon_param_info.param;
let new_ty = anon_param_info.param_ty;
let new_ty_span = anon_param_info.param_ty_span;
let br = anon_param_info.bound_region;
let br = anon_param_info.br;
let is_first = anon_param_info.is_first;
let scope_def_id = region_info.def_id;
let scope_def_id = region_info.scope;
let is_impl_item = region_info.is_impl_item;

match br {
Expand All @@ -73,7 +73,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
return None;
}

if find_anon_type(self.tcx(), self.generic_param_scope, anon, &br).is_some()
if find_anon_type(self.tcx(), self.generic_param_scope, anon).is_some()
&& self.is_self_anon(is_first, scope_def_id)
{
return None;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
// This may have a closure and it would cause ICE
// through `find_param_with_region` (#78262).
let anon_reg_sup = tcx.is_suitable_region(self.generic_param_scope, *sup_r)?;
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.scope);
if fn_returns.is_empty() {
return None;
}
Expand Down Expand Up @@ -196,7 +196,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {

let mut err = self.tcx().dcx().create_err(diag);

let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.scope);

let mut override_error_code = None;
if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = &sup_origin
Expand Down Expand Up @@ -250,7 +250,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
Some(arg),
captures,
Some((param.param_ty_span, param.param_ty.to_string())),
Some(anon_reg_sup.def_id),
Some(anon_reg_sup.scope),
);

let reported = err.emit();
Expand Down
Loading

0 comments on commit 6f5bf6c

Please sign in to comment.