diff --git a/src/adapter/tests.rs b/src/adapter/tests.rs index 20af2760..434a30c4 100644 --- a/src/adapter/tests.rs +++ b/src/adapter/tests.rs @@ -658,6 +658,38 @@ fn rustdoc_sealed_traits() { sealed: true, public_api_sealed: true, }, + Output { + name: "NonRefRecursiveSealed".into(), + path: vec![], + sealed: true, + public_api_sealed: true, + }, + Output { + name: "NonRefSealedPlusRecursiveBlanket".into(), + path: vec![vec![ + "sealed_traits".into(), + "cyclic_bounds2".into(), + "NonRefSealedPlusRecursiveBlanket".into(), + ]], + sealed: true, + public_api_sealed: true, + }, + Output { + name: "DirectCycleSuper".into(), + path: vec![], + sealed: true, + public_api_sealed: true, + }, + Output { + name: "DirectCycleSub".into(), + path: vec![vec![ + "sealed_traits".into(), + "direct_cycle".into(), + "DirectCycleSub".into(), + ]], + sealed: true, + public_api_sealed: true, + }, Output { name: "HiddenSealed".into(), path: vec![vec![ @@ -1173,6 +1205,29 @@ fn rustdoc_sealed_traits() { sealed: false, public_api_sealed: false, }, + Output { + name: "DirectCycleSuper".into(), + path: vec![vec![ + "sealed_traits".into(), + "doc_hidden".into(), + "direct_cycle".into(), + "hidden".into(), + "DirectCycleSuper".into(), + ]], + sealed: false, + public_api_sealed: true, + }, + Output { + name: "DirectCycleSub".into(), + path: vec![vec![ + "sealed_traits".into(), + "doc_hidden".into(), + "direct_cycle".into(), + "DirectCycleSub".into(), + ]], + sealed: false, + public_api_sealed: true, + }, ]; expected_results.sort_unstable(); diff --git a/test_crates/sealed_traits/src/doc_hidden.rs b/test_crates/sealed_traits/src/doc_hidden.rs index a51be81a..819c6549 100644 --- a/test_crates/sealed_traits/src/doc_hidden.rs +++ b/test_crates/sealed_traits/src/doc_hidden.rs @@ -301,3 +301,17 @@ pub trait DeprecatedMethod { pub trait MethodDeprecatedArgType { fn method(&self, token: hidden_module::DeprecatedToken); } + +/// A direct case of two traits declaring blankets on each other. +pub mod direct_cycle { + pub mod hidden { + #[doc(hidden)] + pub trait DirectCycleSuper {} + } + + pub trait DirectCycleSub: hidden::DirectCycleSuper {} + + impl hidden::DirectCycleSuper for T {} + + impl DirectCycleSub for T {} +} diff --git a/test_crates/sealed_traits/src/lib.rs b/test_crates/sealed_traits/src/lib.rs index 160f4a7d..b96939d3 100644 --- a/test_crates/sealed_traits/src/lib.rs +++ b/test_crates/sealed_traits/src/lib.rs @@ -380,3 +380,42 @@ pub mod cyclic_bounds { impl SealedPlusRecursiveBlanket for &T {} } + +/// Another variation of the above idea. +/// In this one, we use `T` instead of `&T` which also suprisingly compiles. +pub mod cyclic_bounds2 { + mod recursive { + pub trait NonRefRecursiveSealed {} + + impl NonRefRecursiveSealed for T {} + } + + /// This is sealed, here's proof: + /// ```compile_fail + /// struct Example; + /// + /// impl sealed_traits::cyclic_bounds2::NonRefSealedPlusRecursiveBlanket for Example {} + /// ``` + pub trait NonRefSealedPlusRecursiveBlanket: recursive::NonRefRecursiveSealed {} + + impl NonRefSealedPlusRecursiveBlanket for T {} +} + +/// A direct case of two traits declaring blankets on each other. +pub mod direct_cycle { + mod private { + pub trait DirectCycleSuper {} + } + + /// This is sealed here's proof: + /// ```compile_fail + /// struct Example; + /// + /// impl sealed_traits::direct_cycle::DirectCycleSub for Example {} + /// ``` + pub trait DirectCycleSub: private::DirectCycleSuper {} + + impl private::DirectCycleSuper for T {} + + impl DirectCycleSub for T {} +}