Report syntax errors from item level macro expansions
This commit is contained in:
parent
71b50f9f09
commit
d1632c2727
@ -21,7 +21,7 @@
|
|||||||
use once_cell::unsync::OnceCell;
|
use once_cell::unsync::OnceCell;
|
||||||
use profile::Count;
|
use profile::Count;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use syntax::{ast, AstPtr, SyntaxNode, SyntaxNodePtr};
|
use syntax::{ast, AstPtr, Parse, SyntaxNode, SyntaxNodePtr};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
attr::Attrs,
|
attr::Attrs,
|
||||||
@ -137,7 +137,7 @@ pub fn enter_expand<T: ast::AstNode>(
|
|||||||
&mut self,
|
&mut self,
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
macro_call: ast::MacroCall,
|
macro_call: ast::MacroCall,
|
||||||
) -> Result<ExpandResult<Option<(Mark, T)>>, UnresolvedMacro> {
|
) -> Result<ExpandResult<Option<(Mark, Parse<T>)>>, UnresolvedMacro> {
|
||||||
// FIXME: within_limit should support this, instead of us having to extract the error
|
// FIXME: within_limit should support this, instead of us having to extract the error
|
||||||
let mut unresolved_macro_err = None;
|
let mut unresolved_macro_err = None;
|
||||||
|
|
||||||
@ -167,37 +167,37 @@ pub fn enter_expand_id<T: ast::AstNode>(
|
|||||||
&mut self,
|
&mut self,
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
call_id: MacroCallId,
|
call_id: MacroCallId,
|
||||||
) -> ExpandResult<Option<(Mark, T)>> {
|
) -> ExpandResult<Option<(Mark, Parse<T>)>> {
|
||||||
self.within_limit(db, |_this| ExpandResult::ok(Some(call_id)))
|
self.within_limit(db, |_this| ExpandResult::ok(Some(call_id)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_expand_inner(
|
fn enter_expand_inner(
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
call_id: MacroCallId,
|
call_id: MacroCallId,
|
||||||
mut err: Option<ExpandError>,
|
mut error: Option<ExpandError>,
|
||||||
) -> ExpandResult<Option<(HirFileId, SyntaxNode)>> {
|
) -> ExpandResult<Option<InFile<Parse<SyntaxNode>>>> {
|
||||||
if err.is_none() {
|
let file_id = call_id.as_file();
|
||||||
err = db.macro_expand_error(call_id);
|
let ExpandResult { value, err } = db.parse_or_expand_with_err(file_id);
|
||||||
|
|
||||||
|
if error.is_none() {
|
||||||
|
error = err;
|
||||||
}
|
}
|
||||||
|
|
||||||
let file_id = call_id.as_file();
|
let parse = match value {
|
||||||
|
Some(it) => it,
|
||||||
let raw_node = match db.parse_or_expand_with_err(file_id) {
|
|
||||||
// FIXME: report parse errors
|
|
||||||
Some(it) => it.syntax_node(),
|
|
||||||
None => {
|
None => {
|
||||||
// Only `None` if the macro expansion produced no usable AST.
|
// Only `None` if the macro expansion produced no usable AST.
|
||||||
if err.is_none() {
|
if error.is_none() {
|
||||||
tracing::warn!("no error despite `parse_or_expand` failing");
|
tracing::warn!("no error despite `parse_or_expand` failing");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ExpandResult::only_err(err.unwrap_or_else(|| {
|
return ExpandResult::only_err(error.unwrap_or_else(|| {
|
||||||
ExpandError::Other("failed to parse macro invocation".into())
|
ExpandError::Other("failed to parse macro invocation".into())
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ExpandResult { value: Some((file_id, raw_node)), err }
|
ExpandResult { value: Some(InFile::new(file_id, parse)), err: error }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exit(&mut self, db: &dyn DefDatabase, mut mark: Mark) {
|
pub fn exit(&mut self, db: &dyn DefDatabase, mut mark: Mark) {
|
||||||
@ -259,7 +259,7 @@ fn within_limit<F, T: ast::AstNode>(
|
|||||||
&mut self,
|
&mut self,
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
op: F,
|
op: F,
|
||||||
) -> ExpandResult<Option<(Mark, T)>>
|
) -> ExpandResult<Option<(Mark, Parse<T>)>>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self) -> ExpandResult<Option<MacroCallId>>,
|
F: FnOnce(&mut Self) -> ExpandResult<Option<MacroCallId>>,
|
||||||
{
|
{
|
||||||
@ -286,15 +286,15 @@ fn within_limit<F, T: ast::AstNode>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
Self::enter_expand_inner(db, call_id, err).map(|value| {
|
Self::enter_expand_inner(db, call_id, err).map(|value| {
|
||||||
value.and_then(|(new_file_id, node)| {
|
value.and_then(|InFile { file_id, value }| {
|
||||||
let node = T::cast(node)?;
|
let parse = value.cast::<T>()?;
|
||||||
|
|
||||||
self.recursion_depth += 1;
|
self.recursion_depth += 1;
|
||||||
self.cfg_expander.hygiene = Hygiene::new(db.upcast(), new_file_id);
|
self.cfg_expander.hygiene = Hygiene::new(db.upcast(), file_id);
|
||||||
let old_file_id = std::mem::replace(&mut self.current_file_id, new_file_id);
|
let old_file_id = std::mem::replace(&mut self.current_file_id, file_id);
|
||||||
let mark =
|
let mark =
|
||||||
Mark { file_id: old_file_id, bomb: DropBomb::new("expansion mark dropped") };
|
Mark { file_id: old_file_id, bomb: DropBomb::new("expansion mark dropped") };
|
||||||
Some((mark, node))
|
Some((mark, parse))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -824,7 +824,11 @@ fn collect_macro_call<F, T, U>(
|
|||||||
self.db.ast_id_map(self.expander.current_file_id),
|
self.db.ast_id_map(self.expander.current_file_id),
|
||||||
);
|
);
|
||||||
|
|
||||||
let id = collector(self, Some(expansion));
|
if record_diagnostics {
|
||||||
|
// FIXME: Report parse errors here
|
||||||
|
}
|
||||||
|
|
||||||
|
let id = collector(self, Some(expansion.tree()));
|
||||||
self.ast_id_map = prev_ast_id_map;
|
self.ast_id_map = prev_ast_id_map;
|
||||||
self.expander.exit(self.db, mark);
|
self.expander.exit(self.db, mark);
|
||||||
id
|
id
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
use hir_expand::{name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroDefKind};
|
use hir_expand::{name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroDefKind};
|
||||||
use intern::Interned;
|
use intern::Interned;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use syntax::ast;
|
use syntax::{ast, Parse};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
attr::Attrs,
|
attr::Attrs,
|
||||||
@ -604,13 +604,10 @@ fn collect(&mut self, item_tree: &ItemTree, tree_id: TreeId, assoc_items: &[Asso
|
|||||||
continue 'attrs;
|
continue 'attrs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match self.expander.enter_expand_id::<ast::MacroItems>(self.db, call_id) {
|
|
||||||
ExpandResult { value: Some((mark, _)), .. } => {
|
let res = self.expander.enter_expand_id::<ast::MacroItems>(self.db, call_id);
|
||||||
self.collect_macro_items(mark);
|
self.collect_macro_items(res, &|| loc.kind.clone());
|
||||||
continue 'items;
|
continue 'items;
|
||||||
}
|
|
||||||
ExpandResult { .. } => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -641,22 +638,24 @@ fn collect(&mut self, item_tree: &ItemTree, tree_id: TreeId, assoc_items: &[Asso
|
|||||||
self.items.push((item.name.clone(), def.into()));
|
self.items.push((item.name.clone(), def.into()));
|
||||||
}
|
}
|
||||||
AssocItem::MacroCall(call) => {
|
AssocItem::MacroCall(call) => {
|
||||||
if let Some(root) =
|
// TODO: These are the wrong errors to report, report in collect_macro_items instead
|
||||||
self.db.parse_or_expand_with_err(self.expander.current_file_id())
|
let file_id = self.expander.current_file_id();
|
||||||
{
|
let root = self.db.parse_or_expand(file_id);
|
||||||
// FIXME: report parse errors
|
if let Some(root) = root {
|
||||||
let root = root.syntax_node();
|
|
||||||
|
|
||||||
let call = &item_tree[call];
|
let call = &item_tree[call];
|
||||||
|
|
||||||
let ast_id_map = self.db.ast_id_map(self.expander.current_file_id());
|
let ast_id_map = self.db.ast_id_map(file_id);
|
||||||
let call = ast_id_map.get(call.ast_id).to_node(&root);
|
let macro_call = ast_id_map.get(call.ast_id).to_node(&root);
|
||||||
let _cx =
|
let _cx = stdx::panic_context::enter(format!(
|
||||||
stdx::panic_context::enter(format!("collect_items MacroCall: {call}"));
|
"collect_items MacroCall: {macro_call}"
|
||||||
let res = self.expander.enter_expand::<ast::MacroItems>(self.db, call);
|
));
|
||||||
|
if let Ok(res) =
|
||||||
if let Ok(ExpandResult { value: Some((mark, _)), .. }) = res {
|
self.expander.enter_expand::<ast::MacroItems>(self.db, macro_call)
|
||||||
self.collect_macro_items(mark);
|
{
|
||||||
|
self.collect_macro_items(res, &|| hir_expand::MacroCallKind::FnLike {
|
||||||
|
ast_id: InFile::new(file_id, call.ast_id),
|
||||||
|
expand_to: hir_expand::ExpandTo::Items,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -664,7 +663,28 @@ fn collect(&mut self, item_tree: &ItemTree, tree_id: TreeId, assoc_items: &[Asso
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_macro_items(&mut self, mark: Mark) {
|
fn collect_macro_items(
|
||||||
|
&mut self,
|
||||||
|
ExpandResult { value, err }: ExpandResult<Option<(Mark, Parse<ast::MacroItems>)>>,
|
||||||
|
error_call_kind: &dyn Fn() -> hir_expand::MacroCallKind,
|
||||||
|
) {
|
||||||
|
let Some((mark, parse)) = value else { return };
|
||||||
|
|
||||||
|
if let Some(err) = err {
|
||||||
|
self.inactive_diagnostics.push(DefDiagnostic::macro_error(
|
||||||
|
self.module_id.local_id,
|
||||||
|
error_call_kind(),
|
||||||
|
err.to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if let errors @ [_, ..] = parse.errors() {
|
||||||
|
self.inactive_diagnostics.push(DefDiagnostic::macro_expansion_parse_error(
|
||||||
|
self.module_id.local_id,
|
||||||
|
error_call_kind(),
|
||||||
|
errors.into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
let tree_id = item_tree::TreeId::new(self.expander.current_file_id(), None);
|
let tree_id = item_tree::TreeId::new(self.expander.current_file_id(), None);
|
||||||
let item_tree = tree_id.item_tree(self.db);
|
let item_tree = tree_id.item_tree(self.db);
|
||||||
let iter: SmallVec<[_; 2]> =
|
let iter: SmallVec<[_; 2]> =
|
||||||
|
@ -350,7 +350,7 @@ pub(crate) fn fill_implicit_impl_trait_args(
|
|||||||
match expander.enter_expand::<ast::Type>(db, macro_call) {
|
match expander.enter_expand::<ast::Type>(db, macro_call) {
|
||||||
Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
|
Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
|
||||||
let ctx = expander.ctx(db);
|
let ctx = expander.ctx(db);
|
||||||
let type_ref = TypeRef::from_ast(&ctx, expanded);
|
let type_ref = TypeRef::from_ast(&ctx, expanded.tree());
|
||||||
self.fill_implicit_impl_trait_args(db, expander, &type_ref);
|
self.fill_implicit_impl_trait_args(db, expander, &type_ref);
|
||||||
expander.exit(db, mark);
|
expander.exit(db, mark);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,10 @@
|
|||||||
use cfg::{CfgExpr, CfgOptions};
|
use cfg::{CfgExpr, CfgOptions};
|
||||||
use hir_expand::{attrs::AttrId, MacroCallKind};
|
use hir_expand::{attrs::AttrId, MacroCallKind};
|
||||||
use la_arena::Idx;
|
use la_arena::Idx;
|
||||||
use syntax::ast::{self, AnyHasAttrs};
|
use syntax::{
|
||||||
|
ast::{self, AnyHasAttrs},
|
||||||
|
SyntaxError,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
item_tree::{self, ItemTreeId},
|
item_tree::{self, ItemTreeId},
|
||||||
@ -29,6 +32,8 @@ pub enum DefDiagnosticKind {
|
|||||||
|
|
||||||
MacroError { ast: MacroCallKind, message: String },
|
MacroError { ast: MacroCallKind, message: String },
|
||||||
|
|
||||||
|
MacroExpansionParseError { ast: MacroCallKind, errors: Box<[SyntaxError]> },
|
||||||
|
|
||||||
UnimplementedBuiltinMacro { ast: AstId<ast::Macro> },
|
UnimplementedBuiltinMacro { ast: AstId<ast::Macro> },
|
||||||
|
|
||||||
InvalidDeriveTarget { ast: AstId<ast::Item>, id: usize },
|
InvalidDeriveTarget { ast: AstId<ast::Item>, id: usize },
|
||||||
@ -91,7 +96,7 @@ pub(super) fn unresolved_proc_macro(
|
|||||||
Self { in_module: container, kind: DefDiagnosticKind::UnresolvedProcMacro { ast, krate } }
|
Self { in_module: container, kind: DefDiagnosticKind::UnresolvedProcMacro { ast, krate } }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn macro_error(
|
pub(crate) fn macro_error(
|
||||||
container: LocalModuleId,
|
container: LocalModuleId,
|
||||||
ast: MacroCallKind,
|
ast: MacroCallKind,
|
||||||
message: String,
|
message: String,
|
||||||
@ -99,6 +104,20 @@ pub(super) fn macro_error(
|
|||||||
Self { in_module: container, kind: DefDiagnosticKind::MacroError { ast, message } }
|
Self { in_module: container, kind: DefDiagnosticKind::MacroError { ast, message } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn macro_expansion_parse_error(
|
||||||
|
container: LocalModuleId,
|
||||||
|
ast: MacroCallKind,
|
||||||
|
errors: &[SyntaxError],
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
in_module: container,
|
||||||
|
kind: DefDiagnosticKind::MacroExpansionParseError {
|
||||||
|
ast,
|
||||||
|
errors: errors.to_vec().into_boxed_slice(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn unresolved_macro_call(
|
pub(super) fn unresolved_macro_call(
|
||||||
container: LocalModuleId,
|
container: LocalModuleId,
|
||||||
ast: MacroCallKind,
|
ast: MacroCallKind,
|
||||||
|
@ -100,7 +100,10 @@ pub trait ExpandDatabase: SourceDatabase {
|
|||||||
#[salsa::transparent]
|
#[salsa::transparent]
|
||||||
fn parse_or_expand(&self, file_id: HirFileId) -> Option<SyntaxNode>;
|
fn parse_or_expand(&self, file_id: HirFileId) -> Option<SyntaxNode>;
|
||||||
#[salsa::transparent]
|
#[salsa::transparent]
|
||||||
fn parse_or_expand_with_err(&self, file_id: HirFileId) -> Option<Parse<SyntaxNode>>;
|
fn parse_or_expand_with_err(
|
||||||
|
&self,
|
||||||
|
file_id: HirFileId,
|
||||||
|
) -> ExpandResult<Option<Parse<SyntaxNode>>>;
|
||||||
/// Implementation for the macro case.
|
/// Implementation for the macro case.
|
||||||
fn parse_macro_expansion(
|
fn parse_macro_expansion(
|
||||||
&self,
|
&self,
|
||||||
@ -262,11 +265,11 @@ fn parse_or_expand(db: &dyn ExpandDatabase, file_id: HirFileId) -> Option<Syntax
|
|||||||
fn parse_or_expand_with_err(
|
fn parse_or_expand_with_err(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
file_id: HirFileId,
|
file_id: HirFileId,
|
||||||
) -> Option<Parse<SyntaxNode>> {
|
) -> ExpandResult<Option<Parse<SyntaxNode>>> {
|
||||||
match file_id.repr() {
|
match file_id.repr() {
|
||||||
HirFileIdRepr::FileId(file_id) => Some(db.parse(file_id).to_syntax()),
|
HirFileIdRepr::FileId(file_id) => ExpandResult::ok(Some(db.parse(file_id).to_syntax())),
|
||||||
HirFileIdRepr::MacroFile(macro_file) => {
|
HirFileIdRepr::MacroFile(macro_file) => {
|
||||||
db.parse_macro_expansion(macro_file).value.map(|(parse, _)| parse)
|
db.parse_macro_expansion(macro_file).map(|it| it.map(|(parse, _)| parse))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use syntax::{ted, SyntaxNode};
|
use syntax::{ted, Parse, SyntaxNode};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
@ -111,7 +111,7 @@ fn lazy_expand(
|
|||||||
def: &MacroDefId,
|
def: &MacroDefId,
|
||||||
macro_call: InFile<ast::MacroCall>,
|
macro_call: InFile<ast::MacroCall>,
|
||||||
krate: CrateId,
|
krate: CrateId,
|
||||||
) -> ExpandResult<Option<InFile<SyntaxNode>>> {
|
) -> ExpandResult<Option<InFile<Parse<SyntaxNode>>>> {
|
||||||
let ast_id = db.ast_id_map(macro_call.file_id).ast_id(¯o_call.value);
|
let ast_id = db.ast_id_map(macro_call.file_id).ast_id(¯o_call.value);
|
||||||
|
|
||||||
let expand_to = ExpandTo::from_call_site(¯o_call.value);
|
let expand_to = ExpandTo::from_call_site(¯o_call.value);
|
||||||
@ -121,13 +121,8 @@ fn lazy_expand(
|
|||||||
MacroCallKind::FnLike { ast_id: macro_call.with_value(ast_id), expand_to },
|
MacroCallKind::FnLike { ast_id: macro_call.with_value(ast_id), expand_to },
|
||||||
);
|
);
|
||||||
|
|
||||||
let err = db.macro_expand_error(id);
|
db.parse_or_expand_with_err(id.as_file())
|
||||||
let value =
|
.map(|parse| parse.map(|parse| InFile::new(id.as_file(), parse)))
|
||||||
db.parse_or_expand_with_err(id.as_file()).map(|node| InFile::new(id.as_file(), node));
|
|
||||||
// FIXME: report parse errors
|
|
||||||
let value = value.map(|it| it.map(|it| it.syntax_node()));
|
|
||||||
|
|
||||||
ExpandResult { value, err }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eager_macro_recur(
|
fn eager_macro_recur(
|
||||||
@ -183,8 +178,14 @@ fn eager_macro_recur(
|
|||||||
Some(val) => {
|
Some(val) => {
|
||||||
// replace macro inside
|
// replace macro inside
|
||||||
let hygiene = Hygiene::new(db, val.file_id);
|
let hygiene = Hygiene::new(db, val.file_id);
|
||||||
let ExpandResult { value, err: error } =
|
let ExpandResult { value, err: error } = eager_macro_recur(
|
||||||
eager_macro_recur(db, &hygiene, val, krate, macro_resolver)?;
|
db,
|
||||||
|
&hygiene,
|
||||||
|
// FIXME: We discard parse errors here
|
||||||
|
val.map(|it| it.syntax_node()),
|
||||||
|
krate,
|
||||||
|
macro_resolver,
|
||||||
|
)?;
|
||||||
let err = if err.is_none() { error } else { err };
|
let err = if err.is_none() { error } else { err };
|
||||||
ExpandResult { value, err }
|
ExpandResult { value, err }
|
||||||
}
|
}
|
||||||
|
@ -381,7 +381,8 @@ pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
|
|||||||
match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call) {
|
match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call) {
|
||||||
Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
|
Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
|
||||||
let ctx = expander.ctx(self.db.upcast());
|
let ctx = expander.ctx(self.db.upcast());
|
||||||
let type_ref = TypeRef::from_ast(&ctx, expanded);
|
// FIXME: Report syntax errors in expansion here
|
||||||
|
let type_ref = TypeRef::from_ast(&ctx, expanded.tree());
|
||||||
|
|
||||||
drop(expander);
|
drop(expander);
|
||||||
let ty = self.lower_ty(&type_ref);
|
let ty = self.lower_ty(&type_ref);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_def::path::ModPath;
|
use hir_def::path::ModPath;
|
||||||
use hir_expand::{name::Name, HirFileId, InFile};
|
use hir_expand::{name::Name, HirFileId, InFile};
|
||||||
use syntax::{ast, AstPtr, SyntaxNodePtr, TextRange};
|
use syntax::{ast, AstPtr, SyntaxError, SyntaxNodePtr, TextRange};
|
||||||
|
|
||||||
use crate::{AssocItem, Field, Local, MacroKind, Type};
|
use crate::{AssocItem, Field, Local, MacroKind, Type};
|
||||||
|
|
||||||
@ -38,8 +38,9 @@ fn from(d: $diag) -> AnyDiagnostic {
|
|||||||
IncorrectCase,
|
IncorrectCase,
|
||||||
InvalidDeriveTarget,
|
InvalidDeriveTarget,
|
||||||
IncoherentImpl,
|
IncoherentImpl,
|
||||||
MacroError,
|
|
||||||
MacroDefError,
|
MacroDefError,
|
||||||
|
MacroError,
|
||||||
|
MacroExpansionParseError,
|
||||||
MalformedDerive,
|
MalformedDerive,
|
||||||
MismatchedArgCount,
|
MismatchedArgCount,
|
||||||
MissingFields,
|
MissingFields,
|
||||||
@ -132,6 +133,13 @@ pub struct MacroError {
|
|||||||
pub message: String,
|
pub message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
pub struct MacroExpansionParseError {
|
||||||
|
pub node: InFile<SyntaxNodePtr>,
|
||||||
|
pub precise_location: Option<TextRange>,
|
||||||
|
pub errors: Box<[SyntaxError]>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub struct MacroDefError {
|
pub struct MacroDefError {
|
||||||
pub node: InFile<AstPtr<ast::Macro>>,
|
pub node: InFile<AstPtr<ast::Macro>>,
|
||||||
|
@ -87,12 +87,12 @@
|
|||||||
attrs::{HasAttrs, Namespace},
|
attrs::{HasAttrs, Namespace},
|
||||||
diagnostics::{
|
diagnostics::{
|
||||||
AnyDiagnostic, BreakOutsideOfLoop, ExpectedFunction, InactiveCode, IncoherentImpl,
|
AnyDiagnostic, BreakOutsideOfLoop, ExpectedFunction, InactiveCode, IncoherentImpl,
|
||||||
IncorrectCase, InvalidDeriveTarget, MacroDefError, MacroError, MalformedDerive,
|
IncorrectCase, InvalidDeriveTarget, MacroDefError, MacroError, MacroExpansionParseError,
|
||||||
MismatchedArgCount, MissingFields, MissingMatchArms, MissingUnsafe, NeedMut, NoSuchField,
|
MalformedDerive, MismatchedArgCount, MissingFields, MissingMatchArms, MissingUnsafe,
|
||||||
PrivateAssocItem, PrivateField, ReplaceFilterMapNextWithFindMap, TypeMismatch,
|
NeedMut, NoSuchField, PrivateAssocItem, PrivateField, ReplaceFilterMapNextWithFindMap,
|
||||||
UndeclaredLabel, UnimplementedBuiltinMacro, UnreachableLabel, UnresolvedExternCrate,
|
TypeMismatch, UndeclaredLabel, UnimplementedBuiltinMacro, UnreachableLabel,
|
||||||
UnresolvedField, UnresolvedImport, UnresolvedMacroCall, UnresolvedMethodCall,
|
UnresolvedExternCrate, UnresolvedField, UnresolvedImport, UnresolvedMacroCall,
|
||||||
UnresolvedModule, UnresolvedProcMacro, UnusedMut,
|
UnresolvedMethodCall, UnresolvedModule, UnresolvedProcMacro, UnusedMut,
|
||||||
},
|
},
|
||||||
has_source::HasSource,
|
has_source::HasSource,
|
||||||
semantics::{PathResolution, Semantics, SemanticsScope, TypeInfo, VisibleTraits},
|
semantics::{PathResolution, Semantics, SemanticsScope, TypeInfo, VisibleTraits},
|
||||||
@ -753,7 +753,6 @@ fn emit_def_diagnostic_(
|
|||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefDiagnosticKind::UnresolvedProcMacro { ast, krate } => {
|
DefDiagnosticKind::UnresolvedProcMacro { ast, krate } => {
|
||||||
let (node, precise_location, macro_name, kind) = precise_macro_call_location(ast, db);
|
let (node, precise_location, macro_name, kind) = precise_macro_call_location(ast, db);
|
||||||
acc.push(
|
acc.push(
|
||||||
@ -761,7 +760,6 @@ fn emit_def_diagnostic_(
|
|||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefDiagnosticKind::UnresolvedMacroCall { ast, path } => {
|
DefDiagnosticKind::UnresolvedMacroCall { ast, path } => {
|
||||||
let (node, precise_location, _, _) = precise_macro_call_location(ast, db);
|
let (node, precise_location, _, _) = precise_macro_call_location(ast, db);
|
||||||
acc.push(
|
acc.push(
|
||||||
@ -774,12 +772,16 @@ fn emit_def_diagnostic_(
|
|||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefDiagnosticKind::MacroError { ast, message } => {
|
DefDiagnosticKind::MacroError { ast, message } => {
|
||||||
let (node, precise_location, _, _) = precise_macro_call_location(ast, db);
|
let (node, precise_location, _, _) = precise_macro_call_location(ast, db);
|
||||||
acc.push(MacroError { node, precise_location, message: message.clone() }.into());
|
acc.push(MacroError { node, precise_location, message: message.clone() }.into());
|
||||||
}
|
}
|
||||||
|
DefDiagnosticKind::MacroExpansionParseError { ast, errors } => {
|
||||||
|
let (node, precise_location, _, _) = precise_macro_call_location(ast, db);
|
||||||
|
acc.push(
|
||||||
|
MacroExpansionParseError { node, precise_location, errors: errors.clone() }.into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
DefDiagnosticKind::UnimplementedBuiltinMacro { ast } => {
|
DefDiagnosticKind::UnimplementedBuiltinMacro { ast } => {
|
||||||
let node = ast.to_node(db.upcast());
|
let node = ast.to_node(db.upcast());
|
||||||
// Must have a name, otherwise we wouldn't emit it.
|
// Must have a name, otherwise we wouldn't emit it.
|
||||||
|
@ -265,6 +265,19 @@ pub fn diagnostics(
|
|||||||
AnyDiagnostic::InvalidDeriveTarget(d) => handlers::invalid_derive_target::invalid_derive_target(&ctx, &d),
|
AnyDiagnostic::InvalidDeriveTarget(d) => handlers::invalid_derive_target::invalid_derive_target(&ctx, &d),
|
||||||
AnyDiagnostic::MacroDefError(d) => handlers::macro_error::macro_def_error(&ctx, &d),
|
AnyDiagnostic::MacroDefError(d) => handlers::macro_error::macro_def_error(&ctx, &d),
|
||||||
AnyDiagnostic::MacroError(d) => handlers::macro_error::macro_error(&ctx, &d),
|
AnyDiagnostic::MacroError(d) => handlers::macro_error::macro_error(&ctx, &d),
|
||||||
|
AnyDiagnostic::MacroExpansionParseError(d) => {
|
||||||
|
res.extend(d.errors.iter().take(32).map(|err| {
|
||||||
|
{
|
||||||
|
Diagnostic::new(
|
||||||
|
"syntax-error",
|
||||||
|
format!("Syntax Error in Expansion: {err}"),
|
||||||
|
ctx.resolve_precise_location(&d.node.clone(), d.precise_location),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.experimental()
|
||||||
|
}));
|
||||||
|
continue;
|
||||||
|
},
|
||||||
AnyDiagnostic::MalformedDerive(d) => handlers::malformed_derive::malformed_derive(&ctx, &d),
|
AnyDiagnostic::MalformedDerive(d) => handlers::malformed_derive::malformed_derive(&ctx, &d),
|
||||||
AnyDiagnostic::MismatchedArgCount(d) => handlers::mismatched_arg_count::mismatched_arg_count(&ctx, &d),
|
AnyDiagnostic::MismatchedArgCount(d) => handlers::mismatched_arg_count::mismatched_arg_count(&ctx, &d),
|
||||||
AnyDiagnostic::MissingFields(d) => handlers::missing_fields::missing_fields(&ctx, &d),
|
AnyDiagnostic::MissingFields(d) => handlers::missing_fields::missing_fields(&ctx, &d),
|
||||||
|
Loading…
Reference in New Issue
Block a user