Skip to content

Commit e547590

Browse files
committed
Restructure proc-macro loading erros, differentiate hard error property on kind
1 parent 7c3de9d commit e547590

File tree

11 files changed

+105
-63
lines changed

11 files changed

+105
-63
lines changed

crates/base-db/src/input.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//! actual IO. See `vfs` and `project_model` in the `rust-analyzer` crate for how
77
//! actual IO is done and lowered to input.
88
9+
use std::error::Error;
910
use std::hash::BuildHasherDefault;
1011
use std::{fmt, mem, ops};
1112

@@ -22,7 +23,49 @@ use vfs::{AbsPathBuf, AnchoredPath, FileId, VfsPath, file_set::FileSet};
2223

2324
use crate::{CrateWorkspaceData, EditionedFileId, FxIndexSet, RootQueryDb};
2425

25-
pub type ProcMacroPaths = FxHashMap<CrateBuilderId, Result<(String, AbsPathBuf), String>>;
26+
pub type ProcMacroPaths =
27+
FxHashMap<CrateBuilderId, Result<(String, AbsPathBuf), ProcMacroLoadingError>>;
28+
29+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
30+
pub enum ProcMacroLoadingError {
31+
Disabled,
32+
FailedToBuild,
33+
MissingDylibPath,
34+
NotYetBuilt,
35+
NoProcMacros,
36+
ProcMacroSrvError(Box<str>),
37+
}
38+
impl ProcMacroLoadingError {
39+
pub fn is_hard_error(&self) -> bool {
40+
match self {
41+
ProcMacroLoadingError::Disabled | ProcMacroLoadingError::NotYetBuilt => false,
42+
ProcMacroLoadingError::FailedToBuild
43+
| ProcMacroLoadingError::MissingDylibPath
44+
| ProcMacroLoadingError::NoProcMacros
45+
| ProcMacroLoadingError::ProcMacroSrvError(_) => true,
46+
}
47+
}
48+
}
49+
50+
impl Error for ProcMacroLoadingError {}
51+
impl fmt::Display for ProcMacroLoadingError {
52+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53+
match self {
54+
ProcMacroLoadingError::Disabled => write!(f, "proc-macro expansion is disabled"),
55+
ProcMacroLoadingError::FailedToBuild => write!(f, "proc-macro failed to build"),
56+
ProcMacroLoadingError::MissingDylibPath => {
57+
write!(f, "proc-macro crate build data is missing a dylib path")
58+
}
59+
ProcMacroLoadingError::NotYetBuilt => write!(f, "proc-macro not yet built"),
60+
ProcMacroLoadingError::NoProcMacros => {
61+
write!(f, "proc macro library has no proc macros")
62+
}
63+
ProcMacroLoadingError::ProcMacroSrvError(msg) => {
64+
write!(f, "proc macro server error: {msg}")
65+
}
66+
}
67+
}
68+
}
2669

2770
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
2871
pub struct SourceRootId(pub u32);

crates/base-db/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ pub use crate::{
1414
input::{
1515
BuiltCrateData, BuiltDependency, Crate, CrateBuilder, CrateBuilderId, CrateDataBuilder,
1616
CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, CratesIdMap, CratesMap,
17-
DependencyBuilder, Env, ExtraCrateData, LangCrateOrigin, ProcMacroPaths, ReleaseChannel,
18-
SourceRoot, SourceRootId, TargetLayoutLoadResult, UniqueCrateData,
17+
DependencyBuilder, Env, ExtraCrateData, LangCrateOrigin, ProcMacroLoadingError,
18+
ProcMacroPaths, ReleaseChannel, SourceRoot, SourceRootId, TargetLayoutLoadResult,
19+
UniqueCrateData,
1920
},
2021
};
2122
use dashmap::{DashMap, mapref::entry::Entry};

crates/hir-expand/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ impl ExpandErrorKind {
199199
},
200200
&ExpandErrorKind::MissingProcMacroExpander(def_crate) => {
201201
match db.proc_macros_for_crate(def_crate).as_ref().and_then(|it| it.get_error()) {
202-
Some((e, hard_err)) => RenderedExpandError {
203-
message: e.to_owned(),
204-
error: hard_err,
202+
Some(e) => RenderedExpandError {
203+
message: e.to_string(),
204+
error: e.is_hard_error(),
205205
kind: RenderedExpandError::GENERAL_KIND,
206206
},
207207
None => RenderedExpandError {

crates/hir-expand/src/prettify_macro_expansion_.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub fn prettify_macro_expansion(
4646
} else if let Some(crate_name) = &macro_def_crate.extra_data(db).display_name {
4747
make::tokens::ident(crate_name.crate_name().as_str())
4848
} else {
49-
return dollar_crate.clone();
49+
dollar_crate.clone()
5050
}
5151
});
5252
if replacement.text() == "$crate" {

crates/hir-expand/src/proc_macro.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use core::fmt;
44
use std::any::Any;
55
use std::{panic::RefUnwindSafe, sync};
66

7-
use base_db::{Crate, CrateBuilderId, CratesIdMap, Env};
7+
use base_db::{Crate, CrateBuilderId, CratesIdMap, Env, ProcMacroLoadingError};
88
use intern::Symbol;
99
use rustc_hash::FxHashMap;
1010
use span::Span;
@@ -53,8 +53,8 @@ pub enum ProcMacroExpansionError {
5353
System(String),
5454
}
5555

56-
pub type ProcMacroLoadResult = Result<Vec<ProcMacro>, (String, bool)>;
57-
type StoredProcMacroLoadResult = Result<Box<[ProcMacro]>, (Box<str>, bool)>;
56+
pub type ProcMacroLoadResult = Result<Vec<ProcMacro>, ProcMacroLoadingError>;
57+
type StoredProcMacroLoadResult = Result<Box<[ProcMacro]>, ProcMacroLoadingError>;
5858

5959
#[derive(Default, Debug)]
6060
pub struct ProcMacrosBuilder(FxHashMap<CrateBuilderId, Arc<CrateProcMacros>>);
@@ -77,9 +77,7 @@ impl ProcMacrosBuilder {
7777
proc_macros_crate,
7878
match proc_macro {
7979
Ok(it) => Arc::new(CrateProcMacros(Ok(it.into_boxed_slice()))),
80-
Err((e, hard_err)) => {
81-
Arc::new(CrateProcMacros(Err((e.into_boxed_str(), hard_err))))
82-
}
80+
Err(e) => Arc::new(CrateProcMacros(Err(e))),
8381
},
8482
);
8583
}
@@ -139,8 +137,8 @@ impl CrateProcMacros {
139137
)
140138
}
141139

142-
pub fn get_error(&self) -> Option<(&str, bool)> {
143-
self.0.as_ref().err().map(|(e, hard_err)| (&**e, *hard_err))
140+
pub fn get_error(&self) -> Option<&ProcMacroLoadingError> {
141+
self.0.as_ref().err()
144142
}
145143

146144
/// Fetch the [`CustomProcMacroExpander`]s and their corresponding names for the given crate.

crates/hir/src/diagnostics.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,16 @@ pub use hir_ty::{
3636
};
3737

3838
macro_rules! diagnostics {
39-
($($diag:ident $(<$lt:lifetime>)?,)*) => {
39+
($AnyDiagnostic:ident <$db:lifetime> -> $($diag:ident $(<$lt:lifetime>)?,)*) => {
4040
#[derive(Debug)]
41-
pub enum AnyDiagnostic<'db> {$(
41+
pub enum $AnyDiagnostic<$db> {$(
4242
$diag(Box<$diag $(<$lt>)?>),
4343
)*}
4444

4545
$(
46-
impl<'db> From<$diag $(<$lt>)?> for AnyDiagnostic<'db> {
47-
fn from(d: $diag $(<$lt>)?) -> AnyDiagnostic<'db> {
48-
AnyDiagnostic::$diag(Box::new(d))
46+
impl<$db> From<$diag $(<$lt>)?> for $AnyDiagnostic<$db> {
47+
fn from(d: $diag $(<$lt>)?) -> $AnyDiagnostic<$db> {
48+
$AnyDiagnostic::$diag(Box::new(d))
4949
}
5050
}
5151
)*
@@ -66,7 +66,7 @@ macro_rules! diagnostics {
6666
// }, ...
6767
// ]
6868

69-
diagnostics![
69+
diagnostics![AnyDiagnostic<'db> ->
7070
AwaitOutsideOfAsync,
7171
BreakOutsideOfLoop,
7272
CastToUnsized<'db>,

crates/ide-assists/src/handlers/expand_rest_pattern.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ pub(crate) fn expand_rest_pattern(acc: &mut Assists, ctx: &AssistContext<'_>) ->
175175
// ast::TuplePat(it) => (),
176176
// FIXME
177177
// ast::SlicePat(it) => (),
178-
_ => return None,
178+
_ => None,
179179
}
180180
}
181181
}

crates/ide-assists/src/utils.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -912,7 +912,7 @@ fn handle_as_ref_str(
912912
) -> Option<(ReferenceConversionType, bool)> {
913913
let str_type = hir::BuiltinType::str().ty(db);
914914

915-
ty.impls_trait(db, famous_defs.core_convert_AsRef()?, &[str_type.clone()])
915+
ty.impls_trait(db, famous_defs.core_convert_AsRef()?, std::slice::from_ref(&str_type))
916916
.then_some((ReferenceConversionType::AsRefStr, could_deref_to_target(ty, &str_type, db)))
917917
}
918918

@@ -924,10 +924,11 @@ fn handle_as_ref_slice(
924924
let type_argument = ty.type_arguments().next()?;
925925
let slice_type = hir::Type::new_slice(type_argument);
926926

927-
ty.impls_trait(db, famous_defs.core_convert_AsRef()?, &[slice_type.clone()]).then_some((
928-
ReferenceConversionType::AsRefSlice,
929-
could_deref_to_target(ty, &slice_type, db),
930-
))
927+
ty.impls_trait(db, famous_defs.core_convert_AsRef()?, std::slice::from_ref(&slice_type))
928+
.then_some((
929+
ReferenceConversionType::AsRefSlice,
930+
could_deref_to_target(ty, &slice_type, db),
931+
))
931932
}
932933

933934
fn handle_dereferenced(
@@ -937,10 +938,11 @@ fn handle_dereferenced(
937938
) -> Option<(ReferenceConversionType, bool)> {
938939
let type_argument = ty.type_arguments().next()?;
939940

940-
ty.impls_trait(db, famous_defs.core_convert_AsRef()?, &[type_argument.clone()]).then_some((
941-
ReferenceConversionType::Dereferenced,
942-
could_deref_to_target(ty, &type_argument, db),
943-
))
941+
ty.impls_trait(db, famous_defs.core_convert_AsRef()?, std::slice::from_ref(&type_argument))
942+
.then_some((
943+
ReferenceConversionType::Dereferenced,
944+
could_deref_to_target(ty, &type_argument, db),
945+
))
944946
}
945947

946948
fn handle_option_as_ref(

crates/load-cargo/src/lib.rs

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use hir_expand::proc_macro::{
1111
};
1212
use ide_db::{
1313
ChangeWithProcMacros, FxHashMap, RootDatabase,
14-
base_db::{CrateGraphBuilder, Env, SourceRoot, SourceRootId},
14+
base_db::{CrateGraphBuilder, Env, ProcMacroLoadingError, SourceRoot, SourceRootId},
1515
prime_caches,
1616
};
1717
use itertools::Itertools;
@@ -81,19 +81,16 @@ pub fn load_workspace(
8181
ProcMacroServerChoice::Sysroot => ws
8282
.find_sysroot_proc_macro_srv()
8383
.and_then(|it| ProcMacroClient::spawn(&it, extra_env).map_err(Into::into))
84-
.map_err(|e| (e, true)),
85-
ProcMacroServerChoice::Explicit(path) => {
86-
ProcMacroClient::spawn(path, extra_env).map_err(Into::into).map_err(|e| (e, true))
87-
}
88-
ProcMacroServerChoice::None => {
89-
Err((anyhow::format_err!("proc macro server disabled"), false))
90-
}
84+
.map_err(|e| ProcMacroLoadingError::ProcMacroSrvError(e.to_string().into_boxed_str())),
85+
ProcMacroServerChoice::Explicit(path) => ProcMacroClient::spawn(path, extra_env)
86+
.map_err(|e| ProcMacroLoadingError::ProcMacroSrvError(e.to_string().into_boxed_str())),
87+
ProcMacroServerChoice::None => Err(ProcMacroLoadingError::Disabled),
9188
};
9289
match &proc_macro_server {
9390
Ok(server) => {
9491
tracing::info!(path=%server.server_path(), "Proc-macro server started")
9592
}
96-
Err((e, _)) => {
93+
Err(e) => {
9794
tracing::info!(%e, "Failed to start proc-macro server")
9895
}
9996
}
@@ -112,21 +109,18 @@ pub fn load_workspace(
112109
let proc_macros = {
113110
let proc_macro_server = match &proc_macro_server {
114111
Ok(it) => Ok(it),
115-
Err((e, hard_err)) => Err((e.to_string(), *hard_err)),
112+
Err(e) => Err(ProcMacroLoadingError::ProcMacroSrvError(e.to_string().into_boxed_str())),
116113
};
117114
proc_macros
118115
.into_iter()
119116
.map(|(crate_id, path)| {
120117
(
121118
crate_id,
122-
path.map_or_else(
123-
|e| Err((e, true)),
124-
|(_, path)| {
125-
proc_macro_server.as_ref().map_err(Clone::clone).and_then(
126-
|proc_macro_server| load_proc_macro(proc_macro_server, &path, &[]),
127-
)
128-
},
129-
),
119+
path.map_or_else(Err, |(_, path)| {
120+
proc_macro_server.as_ref().map_err(Clone::clone).and_then(
121+
|proc_macro_server| load_proc_macro(proc_macro_server, &path, &[]),
122+
)
123+
}),
130124
)
131125
})
132126
.collect()
@@ -391,11 +385,13 @@ pub fn load_proc_macro(
391385
path: &AbsPath,
392386
ignored_macros: &[Box<str>],
393387
) -> ProcMacroLoadResult {
394-
let res: Result<Vec<_>, String> = (|| {
388+
let res: Result<Vec<_>, _> = (|| {
395389
let dylib = MacroDylib::new(path.to_path_buf());
396-
let vec = server.load_dylib(dylib).map_err(|e| format!("{e}"))?;
390+
let vec = server.load_dylib(dylib).map_err(|e| {
391+
ProcMacroLoadingError::ProcMacroSrvError(format!("{e}").into_boxed_str())
392+
})?;
397393
if vec.is_empty() {
398-
return Err("proc macro library returned no proc macros".to_owned());
394+
return Err(ProcMacroLoadingError::NoProcMacros);
399395
}
400396
Ok(vec
401397
.into_iter()
@@ -412,7 +408,7 @@ pub fn load_proc_macro(
412408
}
413409
Err(e) => {
414410
tracing::warn!("proc-macro loading for {path} failed: {e}");
415-
Err((e, true))
411+
Err(e)
416412
}
417413
}
418414
}

crates/project-model/src/workspace.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use std::{collections::VecDeque, fmt, fs, iter, ops::Deref, sync, thread};
77
use anyhow::Context;
88
use base_db::{
99
CrateBuilderId, CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin,
10-
CrateWorkspaceData, DependencyBuilder, Env, LangCrateOrigin, ProcMacroPaths,
11-
TargetLayoutLoadResult,
10+
CrateWorkspaceData, DependencyBuilder, Env, LangCrateOrigin, ProcMacroLoadingError,
11+
ProcMacroPaths, TargetLayoutLoadResult,
1212
};
1313
use cfg::{CfgAtom, CfgDiff, CfgOptions};
1414
use intern::{Symbol, sym};
@@ -1641,11 +1641,11 @@ fn add_target_crate_root(
16411641
Some((BuildScriptOutput { proc_macro_dylib_path, .. }, has_errors)) => {
16421642
match proc_macro_dylib_path {
16431643
Some(path) => Ok((cargo_name.to_owned(), path.clone())),
1644-
None if has_errors => Err("failed to build proc-macro".to_owned()),
1645-
None => Err("proc-macro crate build data is missing dylib path".to_owned()),
1644+
None if has_errors => Err(ProcMacroLoadingError::FailedToBuild),
1645+
None => Err(ProcMacroLoadingError::MissingDylibPath),
16461646
}
16471647
}
1648-
None => Err("build scripts have not been built".to_owned()),
1648+
None => Err(ProcMacroLoadingError::NotYetBuilt),
16491649
};
16501650
proc_macros.insert(crate_id, proc_macro);
16511651
}

0 commit comments

Comments
 (0)