1 // Test that we properly detect the cycle amongst the traits
2 // here and report an error.
4 use std::panic::RefUnwindSafe;
13 trait SourceDatabase {
21 _runtime: Runtime<RootDatabase>,
23 struct Runtime<DB: Database> {
24 _storage: Box<DB::Storage>,
27 _parse: <ParseQuery as Query<RootDatabase>>::Data,
30 impl Database for RootDatabase {
31 // This would also be an error if we didn't abort compilation on the error
33 type Storage = SalsaStorage;
35 impl HasQueryGroup for RootDatabase {}
36 impl<DB> Query<DB> for ParseQuery
41 type Data = RootDatabase;
43 impl<T> SourceDatabase for T
50 pub(crate) fn goto_implementation(db: &RootDatabase) -> u32 {
51 // This is not satisfied:
53 // - `RootDatabase: SourceDatabase`
54 // - requires `RootDatabase: RefUnwindSafe` + `RootDatabase: HasQueryGroup`
55 // - `RootDatabase: RefUnwindSafe`
56 // - requires `Runtime<RootDatabase>: RefUnwindSafe`
57 // - `Runtime<RootDatabase>: RefUnwindSafe`
58 // - requires `DB::Storage: RefUnwindSafe` (`SalsaStorage: RefUnwindSafe`)
59 // - `SalsaStorage: RefUnwindSafe`
60 // - requires `<ParseQuery as Query<RootDatabase>>::Data: RefUnwindSafe`,
61 // which means `ParseQuery: Query<RootDatabase>`
62 // - `ParseQuery: Query<RootDatabase>`
63 // - requires `RootDatabase: SourceDatabase`,
64 // - `RootDatabase: SourceDatabase` is already on the stack, so we have a
65 // cycle with non-coinductive participants
67 // we used to fail to report an error here because we got the
69 SourceDatabase::parse(db);