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,
31 impl Database for RootDatabase {
32 // This would also be an error if we didn't abort compilation on the error
34 type Storage = SalsaStorage;
36 impl HasQueryGroup for RootDatabase {}
37 impl<DB> Query<DB> for ParseQuery
42 type Data = RootDatabase;
44 impl<T> SourceDatabase for T
51 pub(crate) fn goto_implementation(db: &RootDatabase) -> u32 {
52 // This is not satisfied:
54 // - `RootDatabase: SourceDatabase`
55 // - requires `RootDatabase: RefUnwindSafe` + `RootDatabase: HasQueryGroup`
56 // - `RootDatabase: RefUnwindSafe`
57 // - requires `Runtime<RootDatabase>: RefUnwindSafe`
58 // - `Runtime<RootDatabase>: RefUnwindSafe`
59 // - requires `DB::Storage: RefUnwindSafe` (`SalsaStorage: RefUnwindSafe`)
60 // - `SalsaStorage: RefUnwindSafe`
61 // - requires `<ParseQuery as Query<RootDatabase>>::Data: RefUnwindSafe`,
62 // which means `ParseQuery: Query<RootDatabase>`
63 // - `ParseQuery: Query<RootDatabase>`
64 // - requires `RootDatabase: SourceDatabase`,
65 // - `RootDatabase: SourceDatabase` is already on the stack, so we have a
66 // cycle with non-coinductive participants
68 // we used to fail to report an error here because we got the
70 SourceDatabase::parse(db);