Change:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --I found out about the ICE when my crate could not have its documentation online on (). I managed to narrow it down to the code below. All of the code here builds fine (, ), but on the latest stable and nightly it fails when doing . Originally, came from a separate crate, . To my surprise, using the dependency instead of replicating the symbols to this crate results in a more informative top-level error message of the ICE. With we can instead do: The full project can also be found in . Reproduced on more than one toolchain and platform, among which: Without the dependency: with the dependency : <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
this went build -ice in Regression in
is , cc author:
claim
Minimized: label S-has-mcve A-cross-crate-reexports
WG-prioritization assigning priority (). label -I-prioritize +P-critical
Keeping it open until the fix is backported to beta.
The fix has been backported to beta () and to stable (). Closing.

Discussion:
#[derive(Debug)] pub(crate) enum ContainerTy<'tcx> { Ref(ty::Region<'tcx>), <del> Regular { ty: DefId, args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>, arg: usize }, </del> <ins> Regular { ty: DefId, args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>, has_self: bool, arg: usize, }, </ins> } impl<'tcx> ContainerTy<'tcx> { fn object_lifetime_default(self, tcx: TyCtxt<'tcx>) -> ObjectLifetimeDefault<'tcx> { match self { Self::Ref(region) => ObjectLifetimeDefault::Arg(region), <del> Self::Regular { ty: container, args, arg: index } => { </del> <ins> Self::Regular { ty: container, args, has_self, arg: index } => { </ins> let (DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::TyAlias { .. } <del> | DefKind::Trait | DefKind::AssocTy | DefKind::Variant) = tcx.def_kind(container) </del> <ins> | DefKind::Trait) = tcx.def_kind(container) </ins> else { return ObjectLifetimeDefault::Empty; }; let generics = tcx.generics_of(container); <del> let param = generics.params[index].def_id; let default = tcx.object_lifetime_default(param); </del> <ins> debug_assert_eq!(generics.parent_count, 0); // If the container is a trait object type, the arguments won't contain the self type but the // generics of the corresponding trait will. In such a case, offset the index by one. // For comparison, if the container is a trait inside a bound, the arguments do contain the // self type. let offset = if !has_self && generics.parent.is_none() && generics.has_self { 1 } else { 0 }; let param = generics.params[index + offset].def_id; let default = tcx.object_lifetime_default(param); </ins> match default { rbv::ObjectLifetimeDefault::Param(lifetime) => { <ins> // The index is relative to the parent generics but since we don't have any, // we don't need to translate it. </ins> let index = generics.param_def_id_to_index[&lifetime]; let arg = args.skip_binder()[index as usize].expect_region(); ObjectLifetimeDefault::Arg(arg)

pub(crate) fn ty_args_to_args<'tcx>( cx: &mut DocContext<'tcx>, args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>, <del> mut skip_first: bool, </del> <ins> has_self: bool, </ins> container: Option<DefId>, ) -> Vec<GenericArg> { <ins> let mut skip_first = has_self; </ins> let mut ret_val = Vec::with_capacity(args.skip_binder().len().saturating_sub(if skip_first { 1 } else { 0 }));

container.map(|container| crate::clean::ContainerTy::Regular { ty: container, args, <ins> has_self, </ins> arg: index, }), ))),

pub trait AmbiguousBoundTrait<'a, 'b>: 'a + 'b {} pub struct AmbiguousBoundWrapper<'a, 'b, T: ?Sized + 'a + 'b>(&'a T, &'b T); <ins> // Trait objects inside of another trait object, a trait bound or an associated type. pub trait Inner {} pub trait Outer<T: ?Sized> {} pub trait Base { type Type<T: ?Sized>; } impl Base for () { type Type<T: ?Sized> = (); } pub type NestedTraitObjects = dyn Outer<dyn Inner>; pub fn apit_rpit(o: impl Outer<dyn Inner>) -> impl Outer<dyn Inner> { o } pub type AssocTy = <() as Base>::Type<dyn Inner>; </ins>

// @has user/type.BareAmbiguousBoundStatic.html // @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'o, 'o> + 'static;" pub use dyn_trait::BareAmbiguousBoundStatic; <ins> // Regression test for issue #115179: // @has user/type.NestedTraitObjects.html // @has - '//*[@class="rust item-decl"]//code' "dyn Outer<dyn Inner>;" pub use dyn_trait::NestedTraitObjects; // @has user/fn.apit_rpit.html // @has - '//pre[@class="rust item-decl"]'  //     "apit_rpit(o: impl Outer<dyn Inner>) -> impl Outer<dyn Inner>" pub use dyn_trait::apit_rpit; // @has user/type.AssocTy.html // @has - '//*[@class="rust item-decl"]//code' "<() as Base>::Type<dyn Inner>" pub use dyn_trait::AssocTy; </ins>