use crate::hir::place::Place as HirPlace;
use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
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::mir::interpret::{self, Allocation, ConstValue, Scalar};
use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted};
.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> {
self.mk_bound_variable_kinds(
self.late_bound_vars_map(id.owner)
named_region_map: |tcx, id| resolve_lifetimes_for(tcx, id).defs.get(&id),
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),
_ => None,
},
}
}
-fn compute_object_lifetime_defaults(
- tcx: TyCtxt<'_>,
+fn compute_object_lifetime_defaults<'tcx>(
+ tcx: TyCtxt<'tcx>,
item: &hir::Item<'_>,
-) -> Option<Vec<ObjectLifetimeDefault>> {
+) -> Option<&'tcx [ObjectLifetimeDefault]> {
match item.kind {
hir::ItemKind::Struct(_, ref generics)
| hir::ItemKind::Union(_, ref generics)
/// Scan the bounds and where-clauses on parameters to extract bounds
/// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
/// for each type parameter.
-fn object_lifetime_defaults_for_item(
- tcx: TyCtxt<'_>,
+fn object_lifetime_defaults_for_item<'tcx>(
+ tcx: TyCtxt<'tcx>,
generics: &hir::Generics<'_>,
-) -> Vec<ObjectLifetimeDefault> {
+) -> &'tcx [ObjectLifetimeDefault] {
fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::GenericBound<'_>]) {
for bound in bounds {
if let hir::GenericBound::Outlives(ref lifetime) = *bound {
}
}
- generics
- .params
- .iter()
- .filter_map(|param| match param.kind {
- GenericParamKind::Lifetime { .. } => None,
- GenericParamKind::Type { .. } => {
- let mut set = Set1::Empty;
-
- add_bounds(&mut set, ¶m.bounds);
-
- let param_def_id = tcx.hir().local_def_id(param.hir_id);
- for predicate in generics.where_clause.predicates {
- // Look for `type: ...` where clauses.
- let data = match *predicate {
- hir::WherePredicate::BoundPredicate(ref data) => data,
- _ => continue,
- };
+ let process_param = |param: &hir::GenericParam<'_>| match param.kind {
+ GenericParamKind::Lifetime { .. } => None,
+ GenericParamKind::Type { .. } => {
+ let mut set = Set1::Empty;
- // Ignore `for<'a> type: ...` as they can change what
- // lifetimes mean (although we could "just" handle it).
- if !data.bound_generic_params.is_empty() {
- continue;
- }
+ add_bounds(&mut set, ¶m.bounds);
- let res = match data.bounded_ty.kind {
- hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => path.res,
- _ => continue,
- };
+ let param_def_id = tcx.hir().local_def_id(param.hir_id);
+ for predicate in generics.where_clause.predicates {
+ // Look for `type: ...` where clauses.
+ let data = match *predicate {
+ hir::WherePredicate::BoundPredicate(ref data) => data,
+ _ => continue,
+ };
- if res == Res::Def(DefKind::TyParam, param_def_id.to_def_id()) {
- add_bounds(&mut set, &data.bounds);
- }
+ // Ignore `for<'a> type: ...` as they can change what
+ // lifetimes mean (although we could "just" handle it).
+ if !data.bound_generic_params.is_empty() {
+ continue;
}
- Some(match set {
- Set1::Empty => Set1::Empty,
- Set1::One(name) => {
- if name == hir::LifetimeName::Static {
- Set1::One(Region::Static)
- } else {
- generics
- .params
- .iter()
- .filter_map(|param| match param.kind {
- GenericParamKind::Lifetime { .. } => Some((
- param.hir_id,
- hir::LifetimeName::Param(param.name),
- LifetimeDefOrigin::from_param(param),
- )),
- _ => 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,
- })
- }
- GenericParamKind::Const { .. } => {
- // Generic consts don't impose any constraints.
- //
- // We still store a dummy value here to allow generic parameters
- // in an arbitrary order.
- Some(Set1::Empty)
+ 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);
+ }
}
- })
- .collect()
+
+ Some(match set {
+ Set1::Empty => Set1::Empty,
+ Set1::One(name) => {
+ if name == hir::LifetimeName::Static {
+ Set1::One(Region::Static)
+ } else {
+ generics
+ .params
+ .iter()
+ .filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => Some((
+ param.hir_id,
+ hir::LifetimeName::Param(param.name),
+ LifetimeDefOrigin::from_param(param),
+ )),
+ _ => 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,
+ })
+ }
+ GenericParamKind::Const { .. } => {
+ // Generic consts don't impose any constraints.
+ //
+ // We still store a dummy value here to allow generic parameters
+ // in an arbitrary order.
+ Some(Set1::Empty)
+ }
+ };
+
+ tcx.arena.alloc_from_iter(generics.params.iter().filter_map(process_param))
}
impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
if let Some(def_id) = def_id.as_local() {
let id = self.tcx.hir().local_def_id_to_hir_id(def_id);
self.tcx
- .object_lifetime_defaults(id)
- .as_ref()
+ .object_lifetime_defaults(id.owner)
.unwrap()
.iter()
.map(set_to_region)