diff options
Diffstat (limited to 'crates/ra_proc_macro_srv')
-rw-r--r-- | crates/ra_proc_macro_srv/src/dylib.rs | 20 | ||||
-rw-r--r-- | crates/ra_proc_macro_srv/src/lib.rs | 8 |
2 files changed, 12 insertions, 16 deletions
diff --git a/crates/ra_proc_macro_srv/src/dylib.rs b/crates/ra_proc_macro_srv/src/dylib.rs index 99c83481a..209f61493 100644 --- a/crates/ra_proc_macro_srv/src/dylib.rs +++ b/crates/ra_proc_macro_srv/src/dylib.rs | |||
@@ -109,24 +109,19 @@ impl ProcMacroLibraryLibloading { | |||
109 | } | 109 | } |
110 | } | 110 | } |
111 | 111 | ||
112 | type ProcMacroLibraryImpl = ProcMacroLibraryLibloading; | ||
113 | |||
114 | pub struct Expander { | 112 | pub struct Expander { |
115 | inner: ProcMacroLibraryImpl, | 113 | inner: ProcMacroLibraryLibloading, |
116 | } | 114 | } |
117 | 115 | ||
118 | impl Expander { | 116 | impl Expander { |
119 | pub fn new(lib: &Path) -> Result<Expander, String> { | 117 | pub fn new(lib: &Path) -> io::Result<Expander> { |
120 | // Some libraries for dynamic loading require canonicalized path even when it is | 118 | // Some libraries for dynamic loading require canonicalized path even when it is |
121 | // already absolute | 119 | // already absolute |
122 | let lib = lib | 120 | let lib = lib.canonicalize()?; |
123 | .canonicalize() | ||
124 | .unwrap_or_else(|err| panic!("Cannot canonicalize {}: {:?}", lib.display(), err)); | ||
125 | 121 | ||
126 | // Copy the dylib to temp directory to prevent locking in Windows | 122 | let lib = ensure_file_with_lock_free_access(&lib)?; |
127 | let lib = copy_to_temp_dir(&lib).map_err(|e| e.to_string())?; | ||
128 | 123 | ||
129 | let library = ProcMacroLibraryImpl::open(&lib).map_err(|e| e.to_string())?; | 124 | let library = ProcMacroLibraryLibloading::open(&lib)?; |
130 | 125 | ||
131 | Ok(Expander { inner: library }) | 126 | Ok(Expander { inner: library }) |
132 | } | 127 | } |
@@ -199,8 +194,9 @@ impl Expander { | |||
199 | } | 194 | } |
200 | } | 195 | } |
201 | 196 | ||
197 | /// Copy the dylib to temp directory to prevent locking in Windows | ||
202 | #[cfg(windows)] | 198 | #[cfg(windows)] |
203 | fn copy_to_temp_dir(path: &Path) -> io::Result<PathBuf> { | 199 | fn ensure_file_with_lock_free_access(path: &Path) -> io::Result<PathBuf> { |
204 | let mut to = std::env::temp_dir(); | 200 | let mut to = std::env::temp_dir(); |
205 | let file_name = path.file_name().ok_or_else(|| { | 201 | let file_name = path.file_name().ok_or_else(|| { |
206 | io::Error::new( | 202 | io::Error::new( |
@@ -215,6 +211,6 @@ fn copy_to_temp_dir(path: &Path) -> io::Result<PathBuf> { | |||
215 | } | 211 | } |
216 | 212 | ||
217 | #[cfg(unix)] | 213 | #[cfg(unix)] |
218 | fn copy_to_temp_dir(path: &Path) -> io::Result<PathBuf> { | 214 | fn ensure_file_with_lock_free_access(path: &Path) -> io::Result<PathBuf> { |
219 | Ok(path.to_path_buf()) | 215 | Ok(path.to_path_buf()) |
220 | } | 216 | } |
diff --git a/crates/ra_proc_macro_srv/src/lib.rs b/crates/ra_proc_macro_srv/src/lib.rs index 121f531fd..922bb84bb 100644 --- a/crates/ra_proc_macro_srv/src/lib.rs +++ b/crates/ra_proc_macro_srv/src/lib.rs | |||
@@ -23,7 +23,7 @@ use proc_macro::bridge::client::TokenStream; | |||
23 | use ra_proc_macro::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask}; | 23 | use ra_proc_macro::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask}; |
24 | use std::{ | 24 | use std::{ |
25 | collections::{hash_map::Entry, HashMap}, | 25 | collections::{hash_map::Entry, HashMap}, |
26 | fs::metadata, | 26 | fs, |
27 | path::{Path, PathBuf}, | 27 | path::{Path, PathBuf}, |
28 | time::SystemTime, | 28 | time::SystemTime, |
29 | }; | 29 | }; |
@@ -50,9 +50,9 @@ impl ProcMacroSrv { | |||
50 | } | 50 | } |
51 | 51 | ||
52 | fn expander(&mut self, path: &Path) -> Result<&dylib::Expander, String> { | 52 | fn expander(&mut self, path: &Path) -> Result<&dylib::Expander, String> { |
53 | let time = metadata(path) | 53 | let time = fs::metadata(path).and_then(|it| it.modified()).map_err(|err| { |
54 | .and_then(|it| it.modified()) | 54 | format!("Failed to get file metadata for {}: {:?}", path.display(), err) |
55 | .map_err(|err| format!("Failed to file metadata for {}: {:?}", path.display(), err))?; | 55 | })?; |
56 | 56 | ||
57 | Ok(match self.expanders.entry((path.to_path_buf(), time)) { | 57 | Ok(match self.expanders.entry((path.to_path_buf(), time)) { |
58 | Entry::Vacant(v) => v.insert(dylib::Expander::new(path).map_err(|err| { | 58 | Entry::Vacant(v) => v.insert(dylib::Expander::new(path).map_err(|err| { |