diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 47b04c33ec1c..df0687b22249 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -499,7 +499,9 @@ impl<'hir> Map<'hir> { let def_kind = self.tcx.def_kind(def_id); match def_kind { DefKind::Trait | DefKind::TraitAlias => def_id, - DefKind::TyParam | DefKind::ConstParam => self.tcx.local_parent(def_id), + DefKind::LifetimeParam | DefKind::TyParam | DefKind::ConstParam => { + self.tcx.local_parent(def_id) + } _ => bug!("ty_param_owner: {:?} is a {:?} not a type parameter", def_id, def_kind), } } @@ -508,7 +510,9 @@ impl<'hir> Map<'hir> { let def_kind = self.tcx.def_kind(def_id); match def_kind { DefKind::Trait | DefKind::TraitAlias => kw::SelfUpper, - DefKind::TyParam | DefKind::ConstParam => self.tcx.item_name(def_id.to_def_id()), + DefKind::LifetimeParam | DefKind::TyParam | DefKind::ConstParam => { + self.tcx.item_name(def_id.to_def_id()) + } _ => bug!("ty_param_name: {:?} is a {:?} not a type parameter", def_id, def_kind), } } diff --git a/compiler/rustc_middle/src/middle/resolve_lifetime.rs b/compiler/rustc_middle/src/middle/resolve_lifetime.rs index 9b2f44567053..05f4ab487ef6 100644 --- a/compiler/rustc_middle/src/middle/resolve_lifetime.rs +++ b/compiler/rustc_middle/src/middle/resolve_lifetime.rs @@ -35,7 +35,13 @@ impl Set1 { } } -pub type ObjectLifetimeDefault = Set1; +#[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)] +pub enum ObjectLifetimeDefault { + Empty, + Static, + Ambiguous, + Param(DefId), +} /// Maps the id of each lifetime reference to the lifetime decl /// that it corresponds to. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 34639c0b0d0c..d8483e7e4091 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1579,7 +1579,7 @@ rustc_queries! { /// 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 `struct Foo<'a, T: 'a, U>`, this would instead be `['a, 'static]`. - query object_lifetime_defaults(_: DefId) -> Option<&'tcx [ObjectLifetimeDefault]> { + query object_lifetime_defaults(_: LocalDefId) -> Option<&'tcx [ObjectLifetimeDefault]> { desc { "looking up lifetime defaults for a region on an item" } } query late_bound_vars_map(_: LocalDefId) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index f52db86733b6..b96968f81e0a 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -290,24 +290,7 @@ pub fn provide(providers: &mut ty::query::Providers) { named_region_map: |tcx, id| resolve_lifetimes_for(tcx, id).defs.get(&id), is_late_bound_map, - object_lifetime_defaults: |tcx, def_id| { - if let Some(def_id) = def_id.as_local() { - match tcx.hir().get_by_def_id(def_id) { - Node::Item(item) => compute_object_lifetime_defaults(tcx, item), - _ => None, - } - } else { - Some(tcx.arena.alloc_from_iter(tcx.generics_of(def_id).params.iter().filter_map( - |param| match param.kind { - GenericParamDefKind::Type { object_lifetime_default, .. } => { - Some(object_lifetime_default) - } - GenericParamDefKind::Const { .. } => Some(Set1::Empty), - GenericParamDefKind::Lifetime => None, - }, - ))) - } - }, + object_lifetime_defaults, late_bound_vars_map: |tcx, id| resolve_lifetimes_for(tcx, id).late_bound_vars.get(&id), ..*providers @@ -1281,10 +1264,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } -fn compute_object_lifetime_defaults<'tcx>( +fn object_lifetime_defaults<'tcx>( tcx: TyCtxt<'tcx>, - item: &hir::Item<'_>, + def_id: LocalDefId, ) -> Option<&'tcx [ObjectLifetimeDefault]> { + let hir::Node::Item(item) = tcx.hir().get_by_def_id(def_id) else { return None; }; match item.kind { hir::ItemKind::Struct(_, ref generics) | hir::ItemKind::Union(_, ref generics) @@ -1304,24 +1288,13 @@ fn compute_object_lifetime_defaults<'tcx>( let object_lifetime_default_reprs: String = result .iter() .map(|set| match *set { - Set1::Empty => "BaseDefault".into(), - Set1::One(Region::Static) => "'static".into(), - Set1::One(Region::EarlyBound(mut i, _)) => generics - .params - .iter() - .find_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => { - if i == 0 { - return Some(param.name.ident().to_string().into()); - } - i -= 1; - None - } - _ => None, - }) - .unwrap(), - Set1::One(_) => bug!(), - Set1::Many => "Ambiguous".into(), + ObjectLifetimeDefault::Empty => "BaseDefault".into(), + ObjectLifetimeDefault::Static => "'static".into(), + ObjectLifetimeDefault::Param(def_id) => { + let def_id = def_id.expect_local(); + tcx.hir().ty_param_name(def_id).to_string().into() + } + ObjectLifetimeDefault::Ambiguous => "Ambiguous".into(), }) .collect::>>() .join(","); @@ -1376,32 +1349,12 @@ fn object_lifetime_defaults_for_item<'tcx>( } 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 { .. } => { - let param_def_id = tcx.hir().local_def_id(param.hir_id); - Some(( - param_def_id, - hir::LifetimeName::Param(param_def_id, param.name), - )) - } - _ => None, - }) - .enumerate() - .find(|&(_, (_, lt_name))| lt_name == name) - .map_or(Set1::Many, |(i, (def_id, _))| { - Set1::One(Region::EarlyBound(i as u32, def_id.to_def_id())) - }) - } + Set1::Empty => ObjectLifetimeDefault::Empty, + Set1::One(hir::LifetimeName::Static) => ObjectLifetimeDefault::Static, + Set1::One(hir::LifetimeName::Param(param_def_id, _)) => { + ObjectLifetimeDefault::Param(param_def_id.to_def_id()) } - Set1::Many => Set1::Many, + _ => ObjectLifetimeDefault::Ambiguous, }) } GenericParamKind::Const { .. } => { @@ -1409,7 +1362,7 @@ fn object_lifetime_defaults_for_item<'tcx>( // // We still store a dummy value here to allow generic parameters // in an arbitrary order. - Some(Set1::Empty) + Some(ObjectLifetimeDefault::Empty) } }; @@ -1769,24 +1722,37 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { }; let map = &self.map; - let set_to_region = |set: &ObjectLifetimeDefault| match *set { - Set1::Empty => { + let generics = self.tcx.generics_of(def_id); + let set_to_region = |set: ObjectLifetimeDefault| match set { + ObjectLifetimeDefault::Empty => { if in_body { None } else { Some(Region::Static) } } - Set1::One(r) => { - let lifetimes = generic_args.args.iter().filter_map(|arg| match arg { - GenericArg::Lifetime(lt) => Some(lt), + ObjectLifetimeDefault::Static => Some(Region::Static), + ObjectLifetimeDefault::Param(param_def_id) => { + let index = generics.param_def_id_to_index[¶m_def_id]; + generic_args.args.get(index as usize).and_then(|arg| match arg { + GenericArg::Lifetime(lt) => map.defs.get(<.hir_id).copied(), _ => None, - }); - r.subst(lifetimes, map) + }) } - Set1::Many => None, + ObjectLifetimeDefault::Ambiguous => None, }; - self.tcx.object_lifetime_defaults(def_id).unwrap().iter().map(set_to_region).collect() + generics + .params + .iter() + .filter_map(|param| match param.kind { + GenericParamDefKind::Type { object_lifetime_default, .. } => { + Some(object_lifetime_default) + } + GenericParamDefKind::Const { .. } => Some(ObjectLifetimeDefault::Empty), + GenericParamDefKind::Lifetime => None, + }) + .map(set_to_region) + .collect() }); debug!("visit_segment_args: object_lifetime_defaults={:?}", object_lifetime_defaults); diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 8a5c7fee697d..ee184a093918 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -252,9 +252,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }) } }; - debug!("ast_region_to_region(lifetime={:?}) yields {:?}", lifetime, r); - r } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 99996e80c9ce..1c1df4a2f7f9 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -34,6 +34,7 @@ use rustc_hir::weak_lang_items; use rustc_hir::{GenericParamKind, HirId, Node}; use rustc_middle::hir::nested_filter; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; +use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault; use rustc_middle::mir::mono::Linkage; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::InternalSubsts; @@ -1597,7 +1598,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { has_default: false, - object_lifetime_default: rl::Set1::Empty, + object_lifetime_default: ObjectLifetimeDefault::Empty, synthetic: false, }, }); @@ -1671,7 +1672,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { has_default: default.is_some(), object_lifetime_default: object_lifetime_defaults .as_ref() - .map_or(rl::Set1::Empty, |o| o[i]), + .map_or(ObjectLifetimeDefault::Empty, |o| o[i]), synthetic, }; @@ -1727,7 +1728,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { has_default: false, - object_lifetime_default: rl::Set1::Empty, + object_lifetime_default: ObjectLifetimeDefault::Empty, synthetic: false, }, })); @@ -1744,7 +1745,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { has_default: false, - object_lifetime_default: rl::Set1::Empty, + object_lifetime_default: ObjectLifetimeDefault::Empty, synthetic: false, }, });