aboutsummaryrefslogtreecommitdiff
path: root/crates/hir/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir/src/lib.rs')
-rw-r--r--crates/hir/src/lib.rs226
1 files changed, 182 insertions, 44 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index a7c42ca1e..d3ef29db4 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -35,12 +35,18 @@ use std::{iter, sync::Arc};
35 35
36use arrayvec::ArrayVec; 36use arrayvec::ArrayVec;
37use base_db::{CrateDisplayName, CrateId, Edition, FileId}; 37use base_db::{CrateDisplayName, CrateId, Edition, FileId};
38use diagnostics::{
39 InactiveCode, MacroError, UnimplementedBuiltinMacro, UnresolvedExternCrate, UnresolvedImport,
40 UnresolvedMacroCall, UnresolvedModule, UnresolvedProcMacro,
41};
38use either::Either; 42use either::Either;
39use hir_def::{ 43use hir_def::{
40 adt::{ReprKind, VariantData}, 44 adt::{ReprKind, VariantData},
45 body::BodyDiagnostic,
41 expr::{BindingAnnotation, LabelId, Pat, PatId}, 46 expr::{BindingAnnotation, LabelId, Pat, PatId},
42 item_tree::ItemTreeNode, 47 item_tree::ItemTreeNode,
43 lang_item::LangItemTarget, 48 lang_item::LangItemTarget,
49 nameres,
44 per_ns::PerNs, 50 per_ns::PerNs,
45 resolver::{HasResolver, Resolver}, 51 resolver::{HasResolver, Resolver},
46 src::HasSource as _, 52 src::HasSource as _,
@@ -50,11 +56,12 @@ use hir_def::{
50 LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, 56 LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId,
51 TypeParamId, UnionId, 57 TypeParamId, UnionId,
52}; 58};
53use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; 59use hir_expand::{name::name, MacroCallKind, MacroDefKind};
54use hir_ty::{ 60use hir_ty::{
55 autoderef, 61 autoderef,
56 consteval::ConstExt, 62 consteval::ConstExt,
57 could_unify, 63 could_unify,
64 diagnostics_sink::DiagnosticSink,
58 method_resolution::{self, def_crates, TyFingerprint}, 65 method_resolution::{self, def_crates, TyFingerprint},
59 primitive::UintTy, 66 primitive::UintTy,
60 subst_prefix, 67 subst_prefix,
@@ -65,11 +72,12 @@ use hir_ty::{
65 WhereClause, 72 WhereClause,
66}; 73};
67use itertools::Itertools; 74use itertools::Itertools;
75use nameres::diagnostics::DefDiagnosticKind;
68use rustc_hash::FxHashSet; 76use rustc_hash::FxHashSet;
69use stdx::{format_to, impl_from}; 77use stdx::{format_to, impl_from};
70use syntax::{ 78use syntax::{
71 ast::{self, AttrsOwner, NameOwner}, 79 ast::{self, AttrsOwner, NameOwner},
72 AstNode, SmolStr, 80 AstNode, AstPtr, SmolStr, SyntaxKind, SyntaxNodePtr,
73}; 81};
74use tt::{Ident, Leaf, Literal, TokenTree}; 82use tt::{Ident, Leaf, Literal, TokenTree};
75 83
@@ -442,7 +450,131 @@ impl Module {
442 format!("{:?}", self.name(db).map_or("<unknown>".into(), |name| name.to_string())) 450 format!("{:?}", self.name(db).map_or("<unknown>".into(), |name| name.to_string()))
443 }); 451 });
444 let def_map = self.id.def_map(db.upcast()); 452 let def_map = self.id.def_map(db.upcast());
445 def_map.add_diagnostics(db.upcast(), self.id.local_id, sink); 453 for diag in def_map.diagnostics() {
454 if diag.in_module != self.id.local_id {
455 // FIXME: This is accidentally quadratic.
456 continue;
457 }
458 match &diag.kind {
459 DefDiagnosticKind::UnresolvedModule { ast: declaration, candidate } => {
460 let decl = declaration.to_node(db.upcast());
461 sink.push(UnresolvedModule {
462 file: declaration.file_id,
463 decl: AstPtr::new(&decl),
464 candidate: candidate.clone(),
465 })
466 }
467 DefDiagnosticKind::UnresolvedExternCrate { ast } => {
468 let item = ast.to_node(db.upcast());
469 sink.push(UnresolvedExternCrate {
470 file: ast.file_id,
471 item: AstPtr::new(&item),
472 });
473 }
474
475 DefDiagnosticKind::UnresolvedImport { id, index } => {
476 let file_id = id.file_id();
477 let item_tree = id.item_tree(db.upcast());
478 let import = &item_tree[id.value];
479
480 let use_tree = import.use_tree_to_ast(db.upcast(), file_id, *index);
481 sink.push(UnresolvedImport { file: file_id, node: AstPtr::new(&use_tree) });
482 }
483
484 DefDiagnosticKind::UnconfiguredCode { ast, cfg, opts } => {
485 let item = ast.to_node(db.upcast());
486 sink.push(InactiveCode {
487 file: ast.file_id,
488 node: AstPtr::new(&item).into(),
489 cfg: cfg.clone(),
490 opts: opts.clone(),
491 });
492 }
493
494 DefDiagnosticKind::UnresolvedProcMacro { ast } => {
495 let mut precise_location = None;
496 let (file, ast, name) = match ast {
497 MacroCallKind::FnLike { ast_id, .. } => {
498 let node = ast_id.to_node(db.upcast());
499 (ast_id.file_id, SyntaxNodePtr::from(AstPtr::new(&node)), None)
500 }
501 MacroCallKind::Derive { ast_id, derive_name, .. } => {
502 let node = ast_id.to_node(db.upcast());
503
504 // Compute the precise location of the macro name's token in the derive
505 // list.
506 // FIXME: This does not handle paths to the macro, but neither does the
507 // rest of r-a.
508 let derive_attrs =
509 node.attrs().filter_map(|attr| match attr.as_simple_call() {
510 Some((name, args)) if name == "derive" => Some(args),
511 _ => None,
512 });
513 'outer: for attr in derive_attrs {
514 let tokens =
515 attr.syntax().children_with_tokens().filter_map(|elem| {
516 match elem {
517 syntax::NodeOrToken::Node(_) => None,
518 syntax::NodeOrToken::Token(tok) => Some(tok),
519 }
520 });
521 for token in tokens {
522 if token.kind() == SyntaxKind::IDENT
523 && token.text() == derive_name.as_str()
524 {
525 precise_location = Some(token.text_range());
526 break 'outer;
527 }
528 }
529 }
530
531 (
532 ast_id.file_id,
533 SyntaxNodePtr::from(AstPtr::new(&node)),
534 Some(derive_name.clone()),
535 )
536 }
537 };
538 sink.push(UnresolvedProcMacro {
539 file,
540 node: ast,
541 precise_location,
542 macro_name: name,
543 });
544 }
545
546 DefDiagnosticKind::UnresolvedMacroCall { ast, path } => {
547 let node = ast.to_node(db.upcast());
548 sink.push(UnresolvedMacroCall {
549 file: ast.file_id,
550 node: AstPtr::new(&node),
551 path: path.clone(),
552 });
553 }
554
555 DefDiagnosticKind::MacroError { ast, message } => {
556 let (file, ast) = match ast {
557 MacroCallKind::FnLike { ast_id, .. } => {
558 let node = ast_id.to_node(db.upcast());
559 (ast_id.file_id, SyntaxNodePtr::from(AstPtr::new(&node)))
560 }
561 MacroCallKind::Derive { ast_id, .. } => {
562 let node = ast_id.to_node(db.upcast());
563 (ast_id.file_id, SyntaxNodePtr::from(AstPtr::new(&node)))
564 }
565 };
566 sink.push(MacroError { file, node: ast, message: message.clone() });
567 }
568
569 DefDiagnosticKind::UnimplementedBuiltinMacro { ast } => {
570 let node = ast.to_node(db.upcast());
571 // Must have a name, otherwise we wouldn't emit it.
572 let name = node.name().expect("unimplemented builtin macro with no name");
573 let ptr = SyntaxNodePtr::from(AstPtr::new(&name));
574 sink.push(UnimplementedBuiltinMacro { file: ast.file_id, node: ptr });
575 }
576 }
577 }
446 for decl in self.declarations(db) { 578 for decl in self.declarations(db) {
447 match decl { 579 match decl {
448 crate::ModuleDef::Function(f) => f.diagnostics(db, sink), 580 crate::ModuleDef::Function(f) => f.diagnostics(db, sink),
@@ -513,9 +645,8 @@ impl Field {
513 } 645 }
514 646
515 /// Returns the type as in the signature of the struct (i.e., with 647 /// Returns the type as in the signature of the struct (i.e., with
516 /// placeholder types for type parameters). This is good for showing 648 /// placeholder types for type parameters). Only use this in the context of
517 /// signature help, but not so good to actually get the type of the field 649 /// the field definition.
518 /// when you actually have a variable of the struct.
519 pub fn ty(&self, db: &dyn HirDatabase) -> Type { 650 pub fn ty(&self, db: &dyn HirDatabase) -> Type {
520 let var_id = self.parent.into(); 651 let var_id = self.parent.into();
521 let generic_def_id: GenericDefId = match self.parent { 652 let generic_def_id: GenericDefId = match self.parent {
@@ -552,10 +683,6 @@ impl Struct {
552 Module { id: self.id.lookup(db.upcast()).container } 683 Module { id: self.id.lookup(db.upcast()).container }
553 } 684 }
554 685
555 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
556 Some(self.module(db).krate())
557 }
558
559 pub fn name(self, db: &dyn HirDatabase) -> Name { 686 pub fn name(self, db: &dyn HirDatabase) -> Name {
560 db.struct_data(self.id).name.clone() 687 db.struct_data(self.id).name.clone()
561 } 688 }
@@ -640,10 +767,6 @@ impl Enum {
640 Module { id: self.id.lookup(db.upcast()).container } 767 Module { id: self.id.lookup(db.upcast()).container }
641 } 768 }
642 769
643 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
644 Some(self.module(db).krate())
645 }
646
647 pub fn name(self, db: &dyn HirDatabase) -> Name { 770 pub fn name(self, db: &dyn HirDatabase) -> Name {
648 db.enum_data(self.id).name.clone() 771 db.enum_data(self.id).name.clone()
649 } 772 }
@@ -673,6 +796,7 @@ impl Variant {
673 pub fn module(self, db: &dyn HirDatabase) -> Module { 796 pub fn module(self, db: &dyn HirDatabase) -> Module {
674 self.parent.module(db) 797 self.parent.module(db)
675 } 798 }
799
676 pub fn parent_enum(self, _db: &dyn HirDatabase) -> Enum { 800 pub fn parent_enum(self, _db: &dyn HirDatabase) -> Enum {
677 self.parent 801 self.parent
678 } 802 }
@@ -729,10 +853,6 @@ impl Adt {
729 } 853 }
730 } 854 }
731 855
732 pub fn krate(self, db: &dyn HirDatabase) -> Crate {
733 self.module(db).krate()
734 }
735
736 pub fn name(self, db: &dyn HirDatabase) -> Name { 856 pub fn name(self, db: &dyn HirDatabase) -> Name {
737 match self { 857 match self {
738 Adt::Struct(s) => s.name(db), 858 Adt::Struct(s) => s.name(db),
@@ -821,10 +941,6 @@ impl Function {
821 self.id.lookup(db.upcast()).module(db.upcast()).into() 941 self.id.lookup(db.upcast()).module(db.upcast()).into()
822 } 942 }
823 943
824 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
825 Some(self.module(db).krate())
826 }
827
828 pub fn name(self, db: &dyn HirDatabase) -> Name { 944 pub fn name(self, db: &dyn HirDatabase) -> Name {
829 db.function_data(self.id).name.clone() 945 db.function_data(self.id).name.clone()
830 } 946 }
@@ -881,7 +997,37 @@ impl Function {
881 997
882 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { 998 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
883 let krate = self.module(db).id.krate(); 999 let krate = self.module(db).id.krate();
884 hir_def::diagnostics::validate_body(db.upcast(), self.id.into(), sink); 1000
1001 let source_map = db.body_with_source_map(self.id.into()).1;
1002 for diag in source_map.diagnostics() {
1003 match diag {
1004 BodyDiagnostic::InactiveCode { node, cfg, opts } => sink.push(InactiveCode {
1005 file: node.file_id,
1006 node: node.value.clone(),
1007 cfg: cfg.clone(),
1008 opts: opts.clone(),
1009 }),
1010 BodyDiagnostic::MacroError { node, message } => sink.push(MacroError {
1011 file: node.file_id,
1012 node: node.value.clone().into(),
1013 message: message.to_string(),
1014 }),
1015 BodyDiagnostic::UnresolvedProcMacro { node } => sink.push(UnresolvedProcMacro {
1016 file: node.file_id,
1017 node: node.value.clone().into(),
1018 precise_location: None,
1019 macro_name: None,
1020 }),
1021 BodyDiagnostic::UnresolvedMacroCall { node, path } => {
1022 sink.push(UnresolvedMacroCall {
1023 file: node.file_id,
1024 node: node.value.clone(),
1025 path: path.clone(),
1026 })
1027 }
1028 }
1029 }
1030
885 hir_ty::diagnostics::validate_module_item(db, krate, self.id.into(), sink); 1031 hir_ty::diagnostics::validate_module_item(db, krate, self.id.into(), sink);
886 hir_ty::diagnostics::validate_body(db, self.id.into(), sink); 1032 hir_ty::diagnostics::validate_body(db, self.id.into(), sink);
887 } 1033 }
@@ -1014,10 +1160,6 @@ impl Const {
1014 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } 1160 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
1015 } 1161 }
1016 1162
1017 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
1018 Some(self.module(db).krate())
1019 }
1020
1021 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 1163 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
1022 db.const_data(self.id).name.clone() 1164 db.const_data(self.id).name.clone()
1023 } 1165 }
@@ -1045,10 +1187,6 @@ impl Static {
1045 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } 1187 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
1046 } 1188 }
1047 1189
1048 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
1049 Some(self.module(db).krate())
1050 }
1051
1052 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 1190 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
1053 db.static_data(self.id).name.clone() 1191 db.static_data(self.id).name.clone()
1054 } 1192 }
@@ -1112,10 +1250,6 @@ impl TypeAlias {
1112 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } 1250 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
1113 } 1251 }
1114 1252
1115 pub fn krate(self, db: &dyn HirDatabase) -> Crate {
1116 self.module(db).krate()
1117 }
1118
1119 pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { 1253 pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> {
1120 db.type_alias_data(self.id).type_ref.as_deref().cloned() 1254 db.type_alias_data(self.id).type_ref.as_deref().cloned()
1121 } 1255 }
@@ -1156,10 +1290,16 @@ impl BuiltinType {
1156 1290
1157#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 1291#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1158pub enum MacroKind { 1292pub enum MacroKind {
1293 /// `macro_rules!` or Macros 2.0 macro.
1159 Declarative, 1294 Declarative,
1160 ProcMacro, 1295 /// A built-in or custom derive.
1161 Derive, 1296 Derive,
1297 /// A built-in function-like macro.
1162 BuiltIn, 1298 BuiltIn,
1299 /// A procedural attribute macro.
1300 Attr,
1301 /// A function-like procedural macro.
1302 ProcMacro,
1163} 1303}
1164 1304
1165#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 1305#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -1189,11 +1329,13 @@ impl MacroDef {
1189 pub fn kind(&self) -> MacroKind { 1329 pub fn kind(&self) -> MacroKind {
1190 match self.id.kind { 1330 match self.id.kind {
1191 MacroDefKind::Declarative(_) => MacroKind::Declarative, 1331 MacroDefKind::Declarative(_) => MacroKind::Declarative,
1192 MacroDefKind::BuiltIn(_, _) => MacroKind::BuiltIn, 1332 MacroDefKind::BuiltIn(_, _) | MacroDefKind::BuiltInEager(_, _) => MacroKind::BuiltIn,
1193 MacroDefKind::BuiltInDerive(_, _) => MacroKind::Derive, 1333 MacroDefKind::BuiltInDerive(_, _) => MacroKind::Derive,
1194 MacroDefKind::BuiltInEager(_, _) => MacroKind::BuiltIn, 1334 MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::CustomDerive, _) => {
1195 // FIXME might be a derive 1335 MacroKind::Derive
1196 MacroDefKind::ProcMacro(_, _) => MacroKind::ProcMacro, 1336 }
1337 MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::Attr, _) => MacroKind::Attr,
1338 MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::FuncLike, _) => MacroKind::ProcMacro,
1197 } 1339 }
1198 } 1340 }
1199} 1341}
@@ -1667,10 +1809,6 @@ impl Impl {
1667 self.id.lookup(db.upcast()).container.into() 1809 self.id.lookup(db.upcast()).container.into()
1668 } 1810 }
1669 1811
1670 pub fn krate(self, db: &dyn HirDatabase) -> Crate {
1671 Crate { id: self.module(db).id.krate() }
1672 }
1673
1674 pub fn is_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> { 1812 pub fn is_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> {
1675 let src = self.source(db)?; 1813 let src = self.source(db)?;
1676 let item = src.file_id.is_builtin_derive(db.upcast())?; 1814 let item = src.file_id.is_builtin_derive(db.upcast())?;