diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 2a450f4b4e8b1..49b1bfb72a355 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1054,7 +1054,19 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { Some(tcx.closure_base_def_id(def_id)) } Node::Item(item) => match item.kind { - ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => impl_trait_fn, + ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => { + impl_trait_fn.or_else(|| { + let parent_id = tcx.hir().get_parent_item(hir_id); + // This opaque type might occur inside another opaque type + // (e.g. `impl Foo>`) + if parent_id != hir_id && parent_id != CRATE_HIR_ID { + debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id); + Some(tcx.hir().local_def_id(parent_id)) + } else { + None + } + }) + } _ => None, }, _ => None, diff --git a/src/test/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs b/src/test/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs new file mode 100644 index 0000000000000..2f844b4a05f5f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs @@ -0,0 +1,32 @@ +// check-pass +// Regression test for issue #67844 +// Ensures that we properly handle nested TAIT occurences +// with generic parameters + +#![feature(type_alias_impl_trait)] + +trait WithAssoc { type AssocType; } + +trait WithParam {} + +type Return = impl WithAssoc>; + +struct MyParam; +impl WithParam for MyParam {} + +struct MyStruct; + +impl WithAssoc for MyStruct { + type AssocType = MyParam; +} + + +fn my_fun() -> Return { + MyStruct +} + +fn my_other_fn() -> impl WithAssoc> { + MyStruct +} + +fn main() {}