1
Fork 0

Use a slice for object_lifetime_defaults.

This commit is contained in:
Camille GILLOT 2022-02-01 18:28:24 +01:00
parent f72f15ca28
commit e52131efad
4 changed files with 74 additions and 87 deletions

View file

@ -1490,9 +1490,7 @@ rustc_queries! {
/// for each parameter if a trait object were to be passed for that parameter. /// for each parameter if a trait object were to be passed for that parameter.
/// For example, for `struct Foo<'a, T, U>`, this would be `['static, 'static]`. /// For example, for `struct Foo<'a, T, U>`, this would be `['static, 'static]`.
/// For `struct Foo<'a, T: 'a, U>`, this would instead be `['a, 'static]`. /// For `struct Foo<'a, T: 'a, U>`, this would instead be `['a, 'static]`.
query object_lifetime_defaults_map(_: LocalDefId) query object_lifetime_defaults(_: LocalDefId) -> Option<&'tcx [ObjectLifetimeDefault]> {
-> Option<Vec<ObjectLifetimeDefault>> {
storage(ArenaCacheSelector<'tcx>)
desc { "looking up lifetime defaults for a region on an item" } desc { "looking up lifetime defaults for a region on an item" }
} }
query late_bound_vars_map(_: LocalDefId) query late_bound_vars_map(_: LocalDefId)

View file

@ -5,7 +5,7 @@ use crate::dep_graph::{DepGraph, DepKind, DepKindStruct};
use crate::hir::place::Place as HirPlace; use crate::hir::place::Place as HirPlace;
use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource}; use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource};
use crate::middle::resolve_lifetime::{self, LifetimeScopeForPath, ObjectLifetimeDefault}; use crate::middle::resolve_lifetime::{self, LifetimeScopeForPath};
use crate::middle::stability; use crate::middle::stability;
use crate::mir::interpret::{self, Allocation, ConstValue, Scalar}; use crate::mir::interpret::{self, Allocation, ConstValue, Scalar};
use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted}; use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted};
@ -2713,10 +2713,6 @@ impl<'tcx> TyCtxt<'tcx> {
.map_or(false, |(owner, set)| owner == id.owner && set.contains(&id.local_id)) .map_or(false, |(owner, set)| owner == id.owner && set.contains(&id.local_id))
} }
pub fn object_lifetime_defaults(self, id: HirId) -> &'tcx Option<Vec<ObjectLifetimeDefault>> {
self.object_lifetime_defaults_map(id.owner)
}
pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> { pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
self.mk_bound_variable_kinds( self.mk_bound_variable_kinds(
self.late_bound_vars_map(id.owner) self.late_bound_vars_map(id.owner)

View file

@ -377,7 +377,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
named_region_map: |tcx, id| resolve_lifetimes_for(tcx, id).defs.get(&id), named_region_map: |tcx, id| resolve_lifetimes_for(tcx, id).defs.get(&id),
is_late_bound_map, is_late_bound_map,
object_lifetime_defaults_map: |tcx, id| match tcx.hir().find_by_def_id(id) { object_lifetime_defaults: |tcx, id| match tcx.hir().find_by_def_id(id) {
Some(Node::Item(item)) => compute_object_lifetime_defaults(tcx, item), Some(Node::Item(item)) => compute_object_lifetime_defaults(tcx, item),
_ => None, _ => None,
}, },
@ -1673,10 +1673,10 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) {
} }
} }
fn compute_object_lifetime_defaults( fn compute_object_lifetime_defaults<'tcx>(
tcx: TyCtxt<'_>, tcx: TyCtxt<'tcx>,
item: &hir::Item<'_>, item: &hir::Item<'_>,
) -> Option<Vec<ObjectLifetimeDefault>> { ) -> Option<&'tcx [ObjectLifetimeDefault]> {
match item.kind { match item.kind {
hir::ItemKind::Struct(_, ref generics) hir::ItemKind::Struct(_, ref generics)
| hir::ItemKind::Union(_, ref generics) | hir::ItemKind::Union(_, ref generics)
@ -1729,10 +1729,10 @@ fn compute_object_lifetime_defaults(
/// Scan the bounds and where-clauses on parameters to extract bounds /// Scan the bounds and where-clauses on parameters to extract bounds
/// of the form `T:'a` so as to determine the `ObjectLifetimeDefault` /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
/// for each type parameter. /// for each type parameter.
fn object_lifetime_defaults_for_item( fn object_lifetime_defaults_for_item<'tcx>(
tcx: TyCtxt<'_>, tcx: TyCtxt<'tcx>,
generics: &hir::Generics<'_>, generics: &hir::Generics<'_>,
) -> Vec<ObjectLifetimeDefault> { ) -> &'tcx [ObjectLifetimeDefault] {
fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::GenericBound<'_>]) { fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::GenericBound<'_>]) {
for bound in bounds { for bound in bounds {
if let hir::GenericBound::Outlives(ref lifetime) = *bound { if let hir::GenericBound::Outlives(ref lifetime) = *bound {
@ -1741,81 +1741,75 @@ fn object_lifetime_defaults_for_item(
} }
} }
generics let process_param = |param: &hir::GenericParam<'_>| match param.kind {
.params GenericParamKind::Lifetime { .. } => None,
.iter() GenericParamKind::Type { .. } => {
.filter_map(|param| match param.kind { let mut set = Set1::Empty;
GenericParamKind::Lifetime { .. } => None,
GenericParamKind::Type { .. } => {
let mut set = Set1::Empty;
add_bounds(&mut set, &param.bounds); add_bounds(&mut set, &param.bounds);
let param_def_id = tcx.hir().local_def_id(param.hir_id); let param_def_id = tcx.hir().local_def_id(param.hir_id);
for predicate in generics.where_clause.predicates { for predicate in generics.where_clause.predicates {
// Look for `type: ...` where clauses. // Look for `type: ...` where clauses.
let data = match *predicate { let data = match *predicate {
hir::WherePredicate::BoundPredicate(ref data) => data, hir::WherePredicate::BoundPredicate(ref data) => data,
_ => continue, _ => continue,
}; };
// Ignore `for<'a> type: ...` as they can change what // Ignore `for<'a> type: ...` as they can change what
// lifetimes mean (although we could "just" handle it). // lifetimes mean (although we could "just" handle it).
if !data.bound_generic_params.is_empty() { if !data.bound_generic_params.is_empty() {
continue; continue;
}
let res = match data.bounded_ty.kind {
hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => path.res,
_ => continue,
};
if res == Res::Def(DefKind::TyParam, param_def_id.to_def_id()) {
add_bounds(&mut set, &data.bounds);
}
} }
Some(match set { let res = match data.bounded_ty.kind {
Set1::Empty => Set1::Empty, hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => path.res,
Set1::One(name) => { _ => continue,
if name == hir::LifetimeName::Static { };
Set1::One(Region::Static)
} else { if res == Res::Def(DefKind::TyParam, param_def_id.to_def_id()) {
generics add_bounds(&mut set, &data.bounds);
.params }
.iter() }
.filter_map(|param| match param.kind {
GenericParamKind::Lifetime { .. } => Some(( Some(match set {
param.hir_id, Set1::Empty => Set1::Empty,
hir::LifetimeName::Param(param.name), Set1::One(name) => {
LifetimeDefOrigin::from_param(param), if name == hir::LifetimeName::Static {
)), Set1::One(Region::Static)
_ => None, } else {
}) generics
.enumerate() .params
.find(|&(_, (_, lt_name, _))| lt_name == name) .iter()
.map_or(Set1::Many, |(i, (id, _, origin))| { .filter_map(|param| match param.kind {
let def_id = tcx.hir().local_def_id(id); GenericParamKind::Lifetime { .. } => Some((
Set1::One(Region::EarlyBound( param.hir_id,
i as u32, hir::LifetimeName::Param(param.name),
def_id.to_def_id(), LifetimeDefOrigin::from_param(param),
origin, )),
)) _ => None,
}) })
} .enumerate()
.find(|&(_, (_, lt_name, _))| lt_name == name)
.map_or(Set1::Many, |(i, (id, _, origin))| {
let def_id = tcx.hir().local_def_id(id);
Set1::One(Region::EarlyBound(i as u32, def_id.to_def_id(), origin))
})
} }
Set1::Many => Set1::Many, }
}) Set1::Many => Set1::Many,
} })
GenericParamKind::Const { .. } => { }
// Generic consts don't impose any constraints. GenericParamKind::Const { .. } => {
// // Generic consts don't impose any constraints.
// We still store a dummy value here to allow generic parameters //
// in an arbitrary order. // We still store a dummy value here to allow generic parameters
Some(Set1::Empty) // in an arbitrary order.
} Some(Set1::Empty)
}) }
.collect() };
tcx.arena.alloc_from_iter(generics.params.iter().filter_map(process_param))
} }
impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
@ -2510,8 +2504,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
if let Some(def_id) = def_id.as_local() { if let Some(def_id) = def_id.as_local() {
let id = self.tcx.hir().local_def_id_to_hir_id(def_id); let id = self.tcx.hir().local_def_id_to_hir_id(def_id);
self.tcx self.tcx
.object_lifetime_defaults(id) .object_lifetime_defaults(id.owner)
.as_ref()
.unwrap() .unwrap()
.iter() .iter()
.map(set_to_region) .map(set_to_region)

View file

@ -1695,7 +1695,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
kind: ty::GenericParamDefKind::Lifetime, kind: ty::GenericParamDefKind::Lifetime,
})); }));
let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id); let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id.owner);
// Now create the real type and const parameters. // Now create the real type and const parameters.
let type_start = own_start - has_self as u32 + params.len() as u32; let type_start = own_start - has_self as u32 + params.len() as u32;