Auto merge of #125468 - BoxyUwU:remove_defid_from_regionparam, r=compiler-errors
Remove `DefId` from `EarlyParamRegion` Currently we represent usages of `Region` parameters via the `ReEarlyParam` or `ReLateParam` variants. The `ReEarlyParam` is effectively equivalent to `TyKind::Param` and `ConstKind::Param` (i.e. it stores a `Symbol` and a `u32` index) however it also stores a `DefId` for the definition of the lifetime parameter. This was used in roughly two places: - Borrowck diagnostics instead of threading the appropriate `body_id` down to relevant locations. Interestingly there were already some places that had to pass down a `DefId` manually. - Some opaque type checking logic was using the `DefId` field to track captured lifetimes I've split this PR up into a commit for generate rote changes to diagnostics code to pass around a `DefId` manually everywhere, and another commit for the opaque type related changes which likely require more careful review as they might change the semantics of lints/errors. Instead of manually passing the `DefId` around everywhere I previously tried to bundle it in with `TypeErrCtxt` but ran into issues with some call sites of `infcx.err_ctxt` being unable to provide a `DefId`, particularly places involved with trait solving and normalization. It might be worth investigating adding some new wrapper type to pass this around everywhere but I think this might be acceptable for now. This pr also has the effect of reducing the size of `EarlyParamRegion` from 16 bytes -> 8 bytes. I wouldn't expect this to have any direct performance improvement however, other variants of `RegionKind` over `8` bytes are all because they contain a `BoundRegionKind` which is, as far as I know, mostly there for diagnostics. If we're ever able to remove this it would shrink the `RegionKind` type from `24` bytes to `12` (and with clever bit packing we might be able to get it to `8` bytes). I am curious what the performance impact would be of removing interning of `Region`'s if we ever manage to shrink `RegionKind` that much. Sidenote: by removing the `DefId` the `Debug` output for `Region` has gotten significantly nicer. As an example see this opaque type debug print before vs after this PR: `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), [DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0, T, DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0])` `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), ['a/#0, T, 'a/#0])` r? `@compiler-errors` (I would like someone who understands the opaque type setup to atleast review the type system commit, but the rest is likely reviewable by anyone)
This commit is contained in:
commit
fec98b3bbc
31 changed files with 320 additions and 212 deletions
|
@ -538,11 +538,9 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
|
|||
// the cases that were stabilized with the `impl_trait_projection`
|
||||
// feature -- see <https://github.com/rust-lang/rust/pull/115659>.
|
||||
if let DefKind::LifetimeParam = tcx.def_kind(def_id)
|
||||
&& let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
|
||||
| ty::ReLateParam(ty::LateParamRegion {
|
||||
bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
|
||||
..
|
||||
}) = *tcx.map_opaque_lifetime_to_parent_lifetime(def_id.expect_local())
|
||||
&& let Some(def_id) = tcx
|
||||
.map_opaque_lifetime_to_parent_lifetime(def_id.expect_local())
|
||||
.opt_param_def_id(tcx, tcx.parent(opaque_def_id.to_def_id()))
|
||||
{
|
||||
shadowed_captures.insert(def_id);
|
||||
}
|
||||
|
@ -585,12 +583,9 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
|
|||
// Check if the lifetime param was captured but isn't named in the precise captures list.
|
||||
if variances[param.index as usize] == ty::Invariant {
|
||||
if let DefKind::OpaqueTy = tcx.def_kind(tcx.parent(param.def_id))
|
||||
&& let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
|
||||
| ty::ReLateParam(ty::LateParamRegion {
|
||||
bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
|
||||
..
|
||||
}) = *tcx
|
||||
&& let Some(def_id) = tcx
|
||||
.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local())
|
||||
.opt_param_def_id(tcx, tcx.parent(opaque_def_id.to_def_id()))
|
||||
{
|
||||
tcx.dcx().emit_err(errors::LifetimeNotCaptured {
|
||||
opaque_span,
|
||||
|
|
|
@ -876,7 +876,8 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
|
|||
ty::ReLateParam(_) => {}
|
||||
// Remap early-bound regions as long as they don't come from the `impl` itself,
|
||||
// in which case we don't really need to renumber them.
|
||||
ty::ReEarlyParam(ebr) if self.tcx.parent(ebr.def_id) != self.impl_def_id => {}
|
||||
ty::ReEarlyParam(ebr)
|
||||
if ebr.index >= self.tcx.generics_of(self.impl_def_id).count() as u32 => {}
|
||||
_ => return Ok(region),
|
||||
}
|
||||
|
||||
|
@ -889,12 +890,8 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
|
|||
);
|
||||
}
|
||||
} else {
|
||||
let guar = match region.kind() {
|
||||
ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
|
||||
| ty::ReLateParam(ty::LateParamRegion {
|
||||
bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
|
||||
..
|
||||
}) => {
|
||||
let guar = match region.opt_param_def_id(self.tcx, self.tcx.parent(self.def_id)) {
|
||||
Some(def_id) => {
|
||||
let return_span = if let ty::Alias(ty::Opaque, opaque_ty) = self.ty.kind() {
|
||||
self.tcx.def_span(opaque_ty.def_id)
|
||||
} else {
|
||||
|
@ -914,7 +911,7 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
|
|||
.with_note(format!("hidden type inferred to be `{}`", self.ty))
|
||||
.emit()
|
||||
}
|
||||
_ => {
|
||||
None => {
|
||||
// This code path is not reached in any tests, but may be
|
||||
// reachable. If this is triggered, it should be converted
|
||||
// to `delayed_bug` and the triggering case turned into a
|
||||
|
@ -928,7 +925,6 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
|
|||
Ok(ty::Region::new_early_param(
|
||||
self.tcx,
|
||||
ty::EarlyParamRegion {
|
||||
def_id: e.def_id,
|
||||
name: e.name,
|
||||
index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32,
|
||||
},
|
||||
|
|
|
@ -675,11 +675,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
|||
let region_param = gat_generics.param_at(*region_a_idx, tcx);
|
||||
let region_param = ty::Region::new_early_param(
|
||||
tcx,
|
||||
ty::EarlyParamRegion {
|
||||
def_id: region_param.def_id,
|
||||
index: region_param.index,
|
||||
name: region_param.name,
|
||||
},
|
||||
ty::EarlyParamRegion { index: region_param.index, name: region_param.name },
|
||||
);
|
||||
// The predicate we expect to see. (In our example,
|
||||
// `Self: 'me`.)
|
||||
|
@ -708,21 +704,13 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
|||
let region_a_param = gat_generics.param_at(*region_a_idx, tcx);
|
||||
let region_a_param = ty::Region::new_early_param(
|
||||
tcx,
|
||||
ty::EarlyParamRegion {
|
||||
def_id: region_a_param.def_id,
|
||||
index: region_a_param.index,
|
||||
name: region_a_param.name,
|
||||
},
|
||||
ty::EarlyParamRegion { index: region_a_param.index, name: region_a_param.name },
|
||||
);
|
||||
// Same for the region.
|
||||
let region_b_param = gat_generics.param_at(*region_b_idx, tcx);
|
||||
let region_b_param = ty::Region::new_early_param(
|
||||
tcx,
|
||||
ty::EarlyParamRegion {
|
||||
def_id: region_b_param.def_id,
|
||||
index: region_b_param.index,
|
||||
name: region_b_param.name,
|
||||
},
|
||||
ty::EarlyParamRegion { index: region_b_param.index, name: region_b_param.name },
|
||||
);
|
||||
// The predicate we expect to see.
|
||||
bounds.insert(
|
||||
|
@ -2101,16 +2089,14 @@ fn lint_redundant_lifetimes<'tcx>(
|
|||
}
|
||||
|
||||
for &victim in &lifetimes[(idx + 1)..] {
|
||||
// We should only have late-bound lifetimes of the `BrNamed` variety,
|
||||
// since we get these signatures straight from `hir_lowering`. And any
|
||||
// other regions (ReError/ReStatic/etc.) shouldn't matter, since we
|
||||
// All region parameters should have a `DefId` available as:
|
||||
// - Late-bound parameters should be of the`BrNamed` variety,
|
||||
// since we get these signatures straight from `hir_lowering`.
|
||||
// - Early-bound parameters unconditionally have a `DefId` available.
|
||||
//
|
||||
// Any other regions (ReError/ReStatic/etc.) shouldn't matter, since we
|
||||
// can't really suggest to remove them.
|
||||
let (ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
|
||||
| ty::ReLateParam(ty::LateParamRegion {
|
||||
bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
|
||||
..
|
||||
})) = victim.kind()
|
||||
else {
|
||||
let Some(def_id) = victim.opt_param_def_id(tcx, owner_id.to_def_id()) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
|
|
|
@ -453,7 +453,6 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
|
|||
poly_trait_ref,
|
||||
|_| {
|
||||
ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion {
|
||||
def_id: item_def_id,
|
||||
index: 0,
|
||||
name: Symbol::intern(<_name),
|
||||
})
|
||||
|
|
|
@ -323,7 +323,7 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
|
|||
if let ty::ReEarlyParam(..) = *orig_lifetime {
|
||||
let dup_lifetime = ty::Region::new_early_param(
|
||||
tcx,
|
||||
ty::EarlyParamRegion { def_id: param.def_id, index: param.index, name: param.name },
|
||||
ty::EarlyParamRegion { index: param.index, name: param.name },
|
||||
);
|
||||
let span = tcx.def_span(param.def_id);
|
||||
predicates.push((
|
||||
|
|
|
@ -280,7 +280,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local());
|
||||
let generics = tcx.generics_of(item_def_id);
|
||||
let index = generics.param_def_id_to_index[&def_id];
|
||||
ty::Region::new_early_param(tcx, ty::EarlyParamRegion { def_id, index, name })
|
||||
ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name })
|
||||
}
|
||||
|
||||
Some(rbv::ResolvedArg::Free(scope, id)) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue