mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 17:28:09 +00:00
Merge #478
478: WIP: implement cancelation via unwinding r=matklad a=matklad This uses https://github.com/salsa-rs/salsa/pull/107 to implement cancellation. Now we can get rid of `Cancelable` wrapper from everywhere except the top-level analyzer library. Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
aef93c918e
8 changed files with 87 additions and 48 deletions
35
Cargo.lock
generated
35
Cargo.lock
generated
|
@ -66,11 +66,10 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.9.3"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -139,7 +138,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -661,7 +660,7 @@ dependencies = [
|
|||
"ra_syntax 0.1.0",
|
||||
"relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"salsa 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"salsa 0.9.1 (git+https://github.com/matklad/salsa?branch=panic-hooks)",
|
||||
"test_utils 0.1.0",
|
||||
]
|
||||
|
||||
|
@ -680,7 +679,7 @@ dependencies = [
|
|||
"ra_syntax 0.1.0",
|
||||
"relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"salsa 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"salsa 0.9.1 (git+https://github.com/matklad/salsa?branch=panic-hooks)",
|
||||
"test_utils 0.1.0",
|
||||
]
|
||||
|
||||
|
@ -700,7 +699,7 @@ dependencies = [
|
|||
"rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"salsa 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"salsa 0.9.1 (git+https://github.com/matklad/salsa?branch=panic-hooks)",
|
||||
"test_utils 0.1.0",
|
||||
"unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -967,10 +966,10 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ron"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -1022,15 +1021,10 @@ name = "ryu"
|
|||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "safemem"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "salsa"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
source = "git+https://github.com/matklad/salsa?branch=panic-hooks#88313c80302c831ebc7601912ab3f11ad37e6bc2"
|
||||
dependencies = [
|
||||
"derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1207,7 +1201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ron 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -1274,7 +1268,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.41"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1489,7 +1483,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e5f34df7a019573fb8bdc7e24a2bfebe51a2a1d6bfdbaeccedb3c41fc574727"
|
||||
"checksum backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b5b493b66e03090ebc4343eb02f94ff944e0cbc9ac6571491d170ba026741eb5"
|
||||
"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
|
||||
"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
|
||||
"checksum base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "621fc7ecb8008f86d7fb9b95356cd692ce9514b80a86d85b397f32a22da7b9e2"
|
||||
"checksum bit-set 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1efcc46c18245a69c38fcc5cc650f16d3a59d034f3106e9ed63748f695730a"
|
||||
"checksum bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4440d5cb623bb7390ae27fec0bb6c61111969860f8e3ae198bfa0663645e67cf"
|
||||
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
||||
|
@ -1579,15 +1573,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1"
|
||||
"checksum relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7790c7f1cc73d831d28dc5a7deb316a006e7848e6a7f467cdb10a0a9e0fb1c"
|
||||
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
|
||||
"checksum ron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c48677d8a9247a4e0d1f3f9cb4b0a8e29167fdc3c04f383a5e669cd7a960ae0f"
|
||||
"checksum ron 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d9cb28ade964585205aaca1f3d41a6297f72e1ad097b49c4bbde033ef86b38d7"
|
||||
"checksum rowan 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9ae7dba5e703f423ceb8646d636c73e6d858a2f8c834808b4565e42ccda9e2"
|
||||
"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619"
|
||||
"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
|
||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
"checksum rusty-fork 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9591f190d2852720b679c21f66ad929f9f1d7bb09d1193c26167586029d8489c"
|
||||
"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
|
||||
"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
|
||||
"checksum salsa 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "442ef4acdb48c0e24ddaf4f3b62555af2d1da7047f2f26acd54ae73010aa0c02"
|
||||
"checksum salsa 0.9.1 (git+https://github.com/matklad/salsa?branch=panic-hooks)" = "<none>"
|
||||
"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
|
||||
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
|
@ -1612,7 +1605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
|
||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||
"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865"
|
||||
"checksum time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "847da467bf0db05882a9e2375934a8a55cffdc9db0d128af1518200260ba1f6c"
|
||||
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
|
||||
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
|
||||
"checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77"
|
||||
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
|
||||
|
|
|
@ -7,3 +7,4 @@ debug = true
|
|||
|
||||
[patch.'crates-io']
|
||||
cargo_metadata = { git = "https://github.com/oli-obk/cargo_metadata.git", rev="f73e27b24e" }
|
||||
salsa = { git = "https://github.com/matklad/salsa", branch = "panic-hooks" }
|
||||
|
|
|
@ -27,6 +27,12 @@ impl Canceled {
|
|||
pub(crate) fn new() -> Canceled {
|
||||
Canceled { _private: () }
|
||||
}
|
||||
|
||||
pub fn throw() -> ! {
|
||||
// We use resume and not panic here to avoid running the panic
|
||||
// hook (that is, to avoid collecting and printing backtrace).
|
||||
std::panic::resume_unwind(Box::new(Canceled::new()))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Canceled {
|
||||
|
|
|
@ -5,6 +5,8 @@ mod input;
|
|||
mod loc2id;
|
||||
pub mod mock;
|
||||
|
||||
use std::panic;
|
||||
|
||||
use ra_syntax::{TextUnit, TextRange, SourceFile, TreePtr};
|
||||
|
||||
pub use crate::{
|
||||
|
@ -18,13 +20,21 @@ pub use crate::{
|
|||
loc2id::LocationIntener,
|
||||
};
|
||||
|
||||
pub trait BaseDatabase: salsa::Database {
|
||||
pub trait BaseDatabase: salsa::Database + panic::RefUnwindSafe {
|
||||
fn check_canceled(&self) -> Cancelable<()> {
|
||||
if self.salsa_runtime().is_current_revision_canceled() {
|
||||
Err(Canceled::new())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
self.salsa_runtime()
|
||||
.if_current_revision_is_canceled(Canceled::throw);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn catch_canceled<F: FnOnce(&Self) -> T + panic::UnwindSafe, T>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> Result<T, Canceled> {
|
||||
panic::catch_unwind(|| f(self)).map_err(|err| match err.downcast::<Canceled>() {
|
||||
Ok(canceled) => *canceled,
|
||||
Err(payload) => panic::resume_unwind(payload),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::hash::Hash;
|
||||
use std::{panic, hash::Hash};
|
||||
|
||||
use parking_lot::Mutex;
|
||||
use rustc_hash::FxHashMap;
|
||||
|
@ -70,6 +70,15 @@ where
|
|||
map: Mutex<Loc2IdMap<LOC, ID>>,
|
||||
}
|
||||
|
||||
impl<LOC, ID> panic::RefUnwindSafe for LocationIntener<LOC, ID>
|
||||
where
|
||||
ID: ArenaId + Clone,
|
||||
LOC: Clone + Eq + Hash,
|
||||
ID: panic::RefUnwindSafe,
|
||||
LOC: panic::RefUnwindSafe,
|
||||
{
|
||||
}
|
||||
|
||||
impl<LOC, ID> Default for LocationIntener<LOC, ID>
|
||||
where
|
||||
ID: ArenaId + Clone,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::sync::Arc;
|
||||
use std::{sync::Arc, panic};
|
||||
|
||||
use parking_lot::Mutex;
|
||||
use salsa::{self, Database};
|
||||
|
@ -18,6 +18,8 @@ pub(crate) struct MockDatabase {
|
|||
file_counter: u32,
|
||||
}
|
||||
|
||||
impl panic::RefUnwindSafe for MockDatabase {}
|
||||
|
||||
impl MockDatabase {
|
||||
pub(crate) fn with_files(fixture: &str) -> (MockDatabase, SourceRoot) {
|
||||
let (db, source_root, position) = MockDatabase::from_fixture(fixture);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::{fmt, sync::Arc};
|
||||
|
||||
use salsa::{self, Database};
|
||||
use ra_db::{LocationIntener, BaseDatabase, FileId};
|
||||
use ra_db::{LocationIntener, BaseDatabase, FileId, Canceled};
|
||||
|
||||
use crate::{symbol_index, LineIndex};
|
||||
|
||||
|
@ -29,6 +29,9 @@ impl salsa::Database for RootDatabase {
|
|||
fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> {
|
||||
&self.runtime
|
||||
}
|
||||
fn on_propagated_panic(&self) -> ! {
|
||||
Canceled::throw()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for RootDatabase {
|
||||
|
|
|
@ -35,7 +35,7 @@ use std::{fmt, sync::Arc};
|
|||
|
||||
use ra_syntax::{SmolStr, SourceFile, TreePtr, SyntaxKind, TextRange, TextUnit};
|
||||
use ra_text_edit::TextEdit;
|
||||
use ra_db::{SyntaxDatabase, FilesDatabase, LocalSyntaxPtr};
|
||||
use ra_db::{SyntaxDatabase, FilesDatabase, LocalSyntaxPtr, BaseDatabase};
|
||||
use rayon::prelude::*;
|
||||
use relative_path::RelativePathBuf;
|
||||
use rustc_hash::FxHashMap;
|
||||
|
@ -420,43 +420,47 @@ impl Analysis {
|
|||
|
||||
/// Fuzzy searches for a symbol.
|
||||
pub fn symbol_search(&self, query: Query) -> Cancelable<Vec<NavigationTarget>> {
|
||||
let res = symbol_index::world_symbols(&*self.db, query)?
|
||||
.into_iter()
|
||||
.map(NavigationTarget::from_symbol)
|
||||
.collect();
|
||||
Ok(res)
|
||||
self.with_db(|db| {
|
||||
let res = symbol_index::world_symbols(db, query)?
|
||||
.into_iter()
|
||||
.map(NavigationTarget::from_symbol)
|
||||
.collect::<Vec<_>>();
|
||||
Ok(res)
|
||||
})?
|
||||
}
|
||||
|
||||
pub fn goto_definition(
|
||||
&self,
|
||||
position: FilePosition,
|
||||
) -> Cancelable<Option<Vec<NavigationTarget>>> {
|
||||
goto_definition::goto_definition(&*self.db, position)
|
||||
self.db
|
||||
.catch_canceled(|db| goto_definition::goto_definition(db, position))?
|
||||
}
|
||||
|
||||
/// Finds all usages of the reference at point.
|
||||
pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> {
|
||||
self.db.find_all_refs(position)
|
||||
self.with_db(|db| db.find_all_refs(position))?
|
||||
}
|
||||
|
||||
/// Returns a short text descrbing element at position.
|
||||
pub fn hover(&self, position: FilePosition) -> Cancelable<Option<RangeInfo<String>>> {
|
||||
hover::hover(&*self.db, position)
|
||||
self.with_db(|db| hover::hover(db, position))?
|
||||
}
|
||||
|
||||
/// Computes parameter information for the given call expression.
|
||||
pub fn call_info(&self, position: FilePosition) -> Cancelable<Option<CallInfo>> {
|
||||
call_info::call_info(&*self.db, position)
|
||||
self.db
|
||||
.catch_canceled(|db| call_info::call_info(db, position))?
|
||||
}
|
||||
|
||||
/// Returns a `mod name;` declaration which created the current module.
|
||||
pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> {
|
||||
self.db.parent_module(position)
|
||||
self.with_db(|db| db.parent_module(position))?
|
||||
}
|
||||
|
||||
/// Returns crates this file belongs too.
|
||||
pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> {
|
||||
self.db.crate_for(file_id)
|
||||
self.with_db(|db| db.crate_for(file_id))?
|
||||
}
|
||||
|
||||
/// Returns the root file of the given crate.
|
||||
|
@ -466,17 +470,21 @@ impl Analysis {
|
|||
|
||||
/// Returns the set of possible targets to run for the current file.
|
||||
pub fn runnables(&self, file_id: FileId) -> Cancelable<Vec<Runnable>> {
|
||||
runnables::runnables(&*self.db, file_id)
|
||||
self.db
|
||||
.catch_canceled(|db| runnables::runnables(db, file_id))?
|
||||
}
|
||||
|
||||
/// Computes syntax highlighting for the given file.
|
||||
pub fn highlight(&self, file_id: FileId) -> Cancelable<Vec<HighlightedRange>> {
|
||||
syntax_highlighting::highlight(&*self.db, file_id)
|
||||
self.db
|
||||
.catch_canceled(|db| syntax_highlighting::highlight(db, file_id))?
|
||||
}
|
||||
|
||||
/// Computes completions at the given position.
|
||||
pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> {
|
||||
let completions = completion::completions(&self.db, position)?;
|
||||
let completions = self
|
||||
.db
|
||||
.catch_canceled(|db| completion::completions(db, position))??;
|
||||
Ok(completions.map(|it| it.into()))
|
||||
}
|
||||
|
||||
|
@ -488,12 +496,12 @@ impl Analysis {
|
|||
|
||||
/// Computes the set of diagnostics for the given file.
|
||||
pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> {
|
||||
self.db.diagnostics(file_id)
|
||||
self.with_db(|db| db.diagnostics(file_id))?
|
||||
}
|
||||
|
||||
/// Computes the type of the expression at the given position.
|
||||
pub fn type_of(&self, frange: FileRange) -> Cancelable<Option<String>> {
|
||||
hover::type_of(&*self.db, frange)
|
||||
self.with_db(|db| hover::type_of(db, frange))?
|
||||
}
|
||||
|
||||
/// Returns the edit required to rename reference at the position to the new
|
||||
|
@ -503,7 +511,14 @@ impl Analysis {
|
|||
position: FilePosition,
|
||||
new_name: &str,
|
||||
) -> Cancelable<Vec<SourceFileEdit>> {
|
||||
self.db.rename(position, new_name)
|
||||
self.with_db(|db| db.rename(position, new_name))?
|
||||
}
|
||||
|
||||
fn with_db<F: FnOnce(&db::RootDatabase) -> T + std::panic::UnwindSafe, T>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> Cancelable<T> {
|
||||
self.db.catch_canceled(f)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue