Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/lib.rs')
-rw-r--r--crates/hir/src/lib.rs116
1 files changed, 103 insertions, 13 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index bcd94a611a..85f33a10fc 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -59,7 +59,9 @@ use hir_def::{
ModuleId, StaticId, StructId, TraitAliasId, TraitId, TupleId, TypeAliasId, TypeOrConstParamId,
TypeParamId, UnionId,
};
-use hir_expand::{attrs::collect_attrs, name::name, proc_macro::ProcMacroKind, MacroCallKind};
+use hir_expand::{
+ attrs::collect_attrs, name::name, proc_macro::ProcMacroKind, AstId, MacroCallKind, ValueResult,
+};
use hir_ty::{
all_super_traits, autoderef, check_orphan_rules,
consteval::{try_const_usize, unknown_const_as_generic, ConstExt},
@@ -79,7 +81,7 @@ use hir_ty::{
use itertools::Itertools;
use nameres::diagnostics::DefDiagnosticKind;
use rustc_hash::FxHashSet;
-use span::Edition;
+use span::{Edition, MacroCallId};
use stdx::{impl_from, never};
use syntax::{
ast::{self, HasAttrs as _, HasName},
@@ -559,6 +561,12 @@ impl Module {
emit_def_diagnostic(db, acc, diag);
}
+ if !self.id.is_block_module() {
+ // These are reported by the body of block modules
+ let scope = &def_map[self.id.local_id].scope;
+ scope.all_macro_calls().for_each(|it| macro_call_diagnostics(db, it, acc));
+ }
+
for def in self.declarations(db) {
match def {
ModuleDef::Module(m) => {
@@ -577,6 +585,10 @@ impl Module {
item.diagnostics(db, acc, style_lints);
}
+ t.all_macro_calls(db)
+ .iter()
+ .for_each(|&(_ast, call_id)| macro_call_diagnostics(db, call_id, acc));
+
acc.extend(def.diagnostics(db, style_lints))
}
ModuleDef::Adt(adt) => {
@@ -621,6 +633,11 @@ impl Module {
// FIXME: Once we diagnose the inputs to builtin derives, we should at least extract those diagnostics somehow
continue;
}
+ impl_def
+ .all_macro_calls(db)
+ .iter()
+ .for_each(|&(_ast, call_id)| macro_call_diagnostics(db, call_id, acc));
+
let ast_id_map = db.ast_id_map(file_id);
for diag in db.impl_data_with_diagnostics(impl_def.id).1.iter() {
@@ -809,6 +826,37 @@ impl Module {
}
}
+fn macro_call_diagnostics(
+ db: &dyn HirDatabase,
+ macro_call_id: MacroCallId,
+ acc: &mut Vec<AnyDiagnostic>,
+) {
+ let Some(e) = db.parse_macro_expansion_error(macro_call_id) else {
+ return;
+ };
+ let ValueResult { value: parse_errors, err } = &*e;
+ if let Some(err) = err {
+ let loc = db.lookup_intern_macro_call(macro_call_id);
+ let (node, precise_location, macro_name, kind) = precise_macro_call_location(&loc.kind, db);
+ let diag = match err {
+ &hir_expand::ExpandError::UnresolvedProcMacro(krate) => {
+ UnresolvedProcMacro { node, precise_location, macro_name, kind, krate }.into()
+ }
+ err => MacroError { node, precise_location, message: err.to_string() }.into(),
+ };
+ acc.push(diag);
+ }
+
+ if !parse_errors.is_empty() {
+ let loc = db.lookup_intern_macro_call(macro_call_id);
+ let (node, precise_location, _, _) = precise_macro_call_location(&loc.kind, db);
+ acc.push(
+ MacroExpansionParseError { node, precise_location, errors: parse_errors.clone() }
+ .into(),
+ )
+ }
+}
+
fn emit_macro_def_diagnostics(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, m: Macro) {
let id = db.macro_def(m.id);
if let hir_expand::db::TokenExpander::DeclarativeMacro(expander) = db.macro_expander(id) {
@@ -888,16 +936,6 @@ fn emit_def_diagnostic_(
.into(),
);
}
- DefDiagnosticKind::MacroError { ast, message } => {
- let (node, precise_location, _, _) = precise_macro_call_location(ast, db);
- 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 } => {
let node = ast.to_node(db.upcast());
// Must have a name, otherwise we wouldn't emit it.
@@ -1489,6 +1527,14 @@ impl Adt {
.map(|arena| arena.1.clone())
}
+ pub fn as_struct(&self) -> Option<Struct> {
+ if let Self::Struct(v) = self {
+ Some(*v)
+ } else {
+ None
+ }
+ }
+
pub fn as_enum(&self) -> Option<Enum> {
if let Self::Enum(v) = self {
Some(*v)
@@ -1636,6 +1682,10 @@ impl DefWithBody {
Module { id: def_map.module_id(DefMap::ROOT) }.diagnostics(db, acc, style_lints);
}
+ source_map
+ .macro_calls()
+ .for_each(|(_ast_id, call_id)| macro_call_diagnostics(db, call_id.macro_call_id, acc));
+
for diag in source_map.diagnostics() {
acc.push(match diag {
BodyDiagnostic::InactiveCode { node, cfg, opts } => {
@@ -2437,6 +2487,14 @@ impl Trait {
.filter(|(_, ty)| !count_required_only || !ty.has_default())
.count()
}
+
+ fn all_macro_calls(&self, db: &dyn HirDatabase) -> Box<[(AstId<ast::Item>, MacroCallId)]> {
+ db.trait_data(self.id)
+ .macro_calls
+ .as_ref()
+ .map(|it| it.as_ref().clone().into_boxed_slice())
+ .unwrap_or_default()
+ }
}
impl HasVisibility for Trait {
@@ -2506,6 +2564,15 @@ impl HasVisibility for TypeAlias {
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct StaticLifetime;
+
+impl StaticLifetime {
+ pub fn name(self) -> Name {
+ known::STATIC_LIFETIME
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct BuiltinType {
pub(crate) inner: hir_def::builtin_type::BuiltinType,
}
@@ -2535,6 +2602,20 @@ impl BuiltinType {
matches!(self.inner, hir_def::builtin_type::BuiltinType::Float(_))
}
+ pub fn is_f32(&self) -> bool {
+ matches!(
+ self.inner,
+ hir_def::builtin_type::BuiltinType::Float(hir_def::builtin_type::BuiltinFloat::F32)
+ )
+ }
+
+ pub fn is_f64(&self) -> bool {
+ matches!(
+ self.inner,
+ hir_def::builtin_type::BuiltinType::Float(hir_def::builtin_type::BuiltinFloat::F64)
+ )
+ }
+
pub fn is_char(&self) -> bool {
matches!(self.inner, hir_def::builtin_type::BuiltinType::Char)
}
@@ -3743,6 +3824,14 @@ impl Impl {
pub fn check_orphan_rules(self, db: &dyn HirDatabase) -> bool {
check_orphan_rules(db, self.id)
}
+
+ fn all_macro_calls(&self, db: &dyn HirDatabase) -> Box<[(AstId<ast::Item>, MacroCallId)]> {
+ db.impl_data(self.id)
+ .macro_calls
+ .as_ref()
+ .map(|it| it.as_ref().clone().into_boxed_slice())
+ .unwrap_or_default()
+ }
}
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -4495,7 +4584,8 @@ impl Type {
name: Option<&Name>,
mut callback: impl FnMut(Function) -> Option<T>,
) -> Option<T> {
- let _p = tracing::span!(tracing::Level::INFO, "iterate_method_candidates").entered();
+ let _p =
+ tracing::span!(tracing::Level::INFO, "iterate_method_candidates_with_traits").entered();
let mut slot = None;
self.iterate_method_candidates_dyn(