From 8bfcd86acbecdac23e6236f6ab0e1732448d4f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sun, 25 Aug 2024 04:44:24 +0200 Subject: [PATCH] Properly deduce the object lifetime default in GAT paths --- .../src/collect/resolve_bound_vars.rs | 31 ++++++++++--------- src/librustdoc/clean/mod.rs | 11 +++---- .../object-lifetime-default-gat.rs | 16 ++++++++++ 3 files changed, 37 insertions(+), 21 deletions(-) create mode 100644 tests/ui/object-lifetime/object-lifetime-default-gat.rs diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index e11d3c9c48b4e..fa9d1142ae64f 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1482,17 +1482,21 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // Figure out if this is a type/trait segment, // which requires object lifetime defaults. - let type_def_id = match res { - Res::Def(DefKind::AssocTy, def_id) if depth == 1 => Some(self.tcx.parent(def_id)), - Res::Def(DefKind::Variant, def_id) if depth == 0 => Some(self.tcx.parent(def_id)), - Res::Def( - DefKind::Struct - | DefKind::Union - | DefKind::Enum - | DefKind::TyAlias - | DefKind::Trait, - def_id, - ) if depth == 0 => Some(def_id), + let type_def_id = match (res, depth) { + (Res::Def(DefKind::AssocTy, def_id), 1) => Some(self.tcx.parent(def_id)), + (Res::Def(DefKind::Variant, def_id), 0) => Some(self.tcx.parent(def_id)), + ( + Res::Def( + DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::TyAlias + | DefKind::Trait + | DefKind::AssocTy, + def_id, + ), + 0, + ) => Some(def_id), _ => None, }; @@ -1536,9 +1540,6 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { let map = &self.map; let generics = self.tcx.generics_of(def_id); - // `type_def_id` points to an item, so there is nothing to inherit generics from. - debug_assert_eq!(generics.parent_count, 0); - let set_to_region = |set: ObjectLifetimeDefault| match set { ObjectLifetimeDefault::Empty => { if in_body { @@ -1549,8 +1550,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } ObjectLifetimeDefault::Static => Some(ResolvedArg::StaticLifetime), ObjectLifetimeDefault::Param(param_def_id) => { - // This index can be used with `generic_args` since `parent_count == 0`. let index = generics.param_def_id_to_index[¶m_def_id] as usize; + let index = index - generics.parent_count; generic_args.args.get(index).and_then(|arg| match arg { GenericArg::Lifetime(lt) => map.defs.get(<.hir_id).copied(), _ => None, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 53757349a9b2c..781753fed9949 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1995,22 +1995,21 @@ impl<'tcx> ContainerTy<'_, 'tcx> { | DefKind::Union | DefKind::Enum | DefKind::TyAlias - | DefKind::Trait) = tcx.def_kind(container) + | DefKind::Trait + | DefKind::AssocTy) = tcx.def_kind(container) else { return ObjectLifetimeDefault::Empty; }; let generics = tcx.generics_of(container); - debug_assert_eq!(generics.parent_count, 0); let param = generics.own_params[index].def_id; let default = tcx.object_lifetime_default(param); match default { rbv::ObjectLifetimeDefault::Param(lifetime) => { - // The index is relative to the parent generics but since we don't have any, - // we don't need to translate it. - let index = generics.param_def_id_to_index[&lifetime]; - let arg = args.skip_binder()[index as usize].expect_region(); + let index = generics.param_def_id_to_index[&lifetime] as usize; + let index = index - generics.parent_count; + let arg = args.skip_binder()[index].expect_region(); ObjectLifetimeDefault::Arg(arg) } rbv::ObjectLifetimeDefault::Empty => ObjectLifetimeDefault::Empty, diff --git a/tests/ui/object-lifetime/object-lifetime-default-gat.rs b/tests/ui/object-lifetime/object-lifetime-default-gat.rs new file mode 100644 index 0000000000000..8f28c23da736a --- /dev/null +++ b/tests/ui/object-lifetime/object-lifetime-default-gat.rs @@ -0,0 +1,16 @@ +// Properly deduce the object lifetime default in generic associated type (GAT) *paths*. +// issue: rust-lang/rust#115379 +//@ check-pass + +trait Outer { + type Ty<'a, T: ?Sized + 'a>; +} +impl Outer for () { + type Ty<'a, T: ?Sized + 'a> = &'a T; +} +trait Inner {} + +fn f<'r>(x: <() as Outer>::Ty<'r, dyn Inner + 'r>) { g(x) } +fn g<'r>(_: <() as Outer>::Ty<'r, dyn Inner>) {} + +fn main() {}