@@ -19,7 +19,7 @@ pub mod path_transform;
1919pub mod search;
2020pub mod rename;
2121
22- use std:: { fmt, sync:: Arc } ;
22+ use std:: { fmt, mem :: ManuallyDrop , sync:: Arc } ;
2323
2424use base_db:: {
2525 salsa:: { self , Durability } ,
@@ -44,7 +44,19 @@ pub use base_db;
4444 hir:: db:: HirDatabaseStorage
4545) ]
4646pub struct RootDatabase {
47- storage : salsa:: Storage < RootDatabase > ,
47+ // We use `ManuallyDrop` here because every codegen unit that contains a
48+ // `&RootDatabase -> &dyn OtherDatabase` cast will instantiate its drop glue in the vtable,
49+ // which duplicates `Weak::drop` and `Arc::drop` tens of thousands of times, which makes
50+ // compile times of all `ide_*` and downstream crates suffer greatly.
51+ storage : ManuallyDrop < salsa:: Storage < RootDatabase > > ,
52+ }
53+
54+ impl Drop for RootDatabase {
55+ fn drop ( & mut self ) {
56+ unsafe {
57+ ManuallyDrop :: drop ( & mut self . storage ) ;
58+ }
59+ }
4860}
4961
5062impl fmt:: Debug for RootDatabase {
@@ -93,7 +105,7 @@ impl Default for RootDatabase {
93105
94106impl RootDatabase {
95107 pub fn new ( lru_capacity : Option < usize > ) -> RootDatabase {
96- let mut db = RootDatabase { storage : salsa:: Storage :: default ( ) } ;
108+ let mut db = RootDatabase { storage : ManuallyDrop :: new ( salsa:: Storage :: default ( ) ) } ;
97109 db. set_crate_graph_with_durability ( Default :: default ( ) , Durability :: HIGH ) ;
98110 db. set_local_roots_with_durability ( Default :: default ( ) , Durability :: HIGH ) ;
99111 db. set_library_roots_with_durability ( Default :: default ( ) , Durability :: HIGH ) ;
@@ -112,7 +124,7 @@ impl RootDatabase {
112124
113125impl salsa:: ParallelDatabase for RootDatabase {
114126 fn snapshot ( & self ) -> salsa:: Snapshot < RootDatabase > {
115- salsa:: Snapshot :: new ( RootDatabase { storage : self . storage . snapshot ( ) } )
127+ salsa:: Snapshot :: new ( RootDatabase { storage : ManuallyDrop :: new ( self . storage . snapshot ( ) ) } )
116128 }
117129}
118130
0 commit comments