blob: 94e718317e7c8c79c79ad2df655d3b9f3c4c475f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
// Test that we properly detect the cycle amongst the traits
// here and report an error.
use std::panic::RefUnwindSafe;
trait Database {
type Storage;
}
trait HasQueryGroup {}
trait Query<DB> {
type Data;
}
trait SourceDatabase {
fn parse(&self) {
loop {}
}
}
struct ParseQuery;
struct RootDatabase {
_runtime: Runtime<RootDatabase>,
}
struct Runtime<DB: Database> {
_storage: Box<DB::Storage>,
}
struct SalsaStorage {
_parse: <ParseQuery as Query<RootDatabase>>::Data,
//~^ ERROR overflow
}
impl Database for RootDatabase {
// This would also be an error if we didn't abort compilation on the error
// above.
type Storage = SalsaStorage;
}
impl HasQueryGroup for RootDatabase {}
impl<DB> Query<DB> for ParseQuery
where
DB: SourceDatabase,
DB: Database,
{
type Data = RootDatabase;
}
impl<T> SourceDatabase for T
where
T: RefUnwindSafe,
T: HasQueryGroup,
{
}
pub(crate) fn goto_implementation(db: &RootDatabase) -> u32 {
// This is not satisfied:
//
// - `RootDatabase: SourceDatabase`
// - requires `RootDatabase: RefUnwindSafe` + `RootDatabase: HasQueryGroup`
// - `RootDatabase: RefUnwindSafe`
// - requires `Runtime<RootDatabase>: RefUnwindSafe`
// - `Runtime<RootDatabase>: RefUnwindSafe`
// - requires `DB::Storage: RefUnwindSafe` (`SalsaStorage: RefUnwindSafe`)
// - `SalsaStorage: RefUnwindSafe`
// - requires `<ParseQuery as Query<RootDatabase>>::Data: RefUnwindSafe`,
// which means `ParseQuery: Query<RootDatabase>`
// - `ParseQuery: Query<RootDatabase>`
// - requires `RootDatabase: SourceDatabase`,
// - `RootDatabase: SourceDatabase` is already on the stack, so we have a
// cycle with non-coinductive participants
//
// we used to fail to report an error here because we got the
// caching wrong.
SourceDatabase::parse(db);
22
}
fn main() {}
|