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.rs360
1 files changed, 257 insertions, 103 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 0bb3767c1..b7eabaabb 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -15,7 +15,7 @@
15//! 15//!
16//! `hir` is what insulates the "we don't know how to actually write an incremental compiler" 16//! `hir` is what insulates the "we don't know how to actually write an incremental compiler"
17//! from the ide with completions, hovers, etc. It is a (soft, internal) boundary: 17//! from the ide with completions, hovers, etc. It is a (soft, internal) boundary:
18//! https://www.tedinski.com/2018/02/06/system-boundaries.html. 18//! <https://www.tedinski.com/2018/02/06/system-boundaries.html>.
19 19
20#![recursion_limit = "512"] 20#![recursion_limit = "512"]
21 21
@@ -35,14 +35,10 @@ 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};
42use either::Either; 38use either::Either;
43use hir_def::{ 39use hir_def::{
44 adt::{ReprKind, VariantData}, 40 adt::{ReprKind, VariantData},
45 body::BodyDiagnostic, 41 body::{BodyDiagnostic, SyntheticSyntax},
46 expr::{BindingAnnotation, LabelId, Pat, PatId}, 42 expr::{BindingAnnotation, LabelId, Pat, PatId},
47 item_tree::ItemTreeNode, 43 item_tree::ItemTreeNode,
48 lang_item::LangItemTarget, 44 lang_item::LangItemTarget,
@@ -60,8 +56,8 @@ use hir_ty::{
60 autoderef, 56 autoderef,
61 consteval::ConstExt, 57 consteval::ConstExt,
62 could_unify, 58 could_unify,
63 diagnostics_sink::DiagnosticSink, 59 diagnostics::BodyValidationDiagnostic,
64 method_resolution::{self, def_crates, TyFingerprint}, 60 method_resolution::{self, TyFingerprint},
65 primitive::UintTy, 61 primitive::UintTy,
66 subst_prefix, 62 subst_prefix,
67 traits::FnTrait, 63 traits::FnTrait,
@@ -72,6 +68,7 @@ use hir_ty::{
72}; 68};
73use itertools::Itertools; 69use itertools::Itertools;
74use nameres::diagnostics::DefDiagnosticKind; 70use nameres::diagnostics::DefDiagnosticKind;
71use once_cell::unsync::Lazy;
75use rustc_hash::FxHashSet; 72use rustc_hash::FxHashSet;
76use stdx::{format_to, impl_from}; 73use stdx::{format_to, impl_from};
77use syntax::{ 74use syntax::{
@@ -84,6 +81,13 @@ use crate::db::{DefDatabase, HirDatabase};
84 81
85pub use crate::{ 82pub use crate::{
86 attrs::{HasAttrs, Namespace}, 83 attrs::{HasAttrs, Namespace},
84 diagnostics::{
85 AnyDiagnostic, BreakOutsideOfLoop, InactiveCode, IncorrectCase, MacroError,
86 MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr,
87 MissingUnsafe, NoSuchField, RemoveThisSemicolon, ReplaceFilterMapNextWithFindMap,
88 UnimplementedBuiltinMacro, UnresolvedExternCrate, UnresolvedImport, UnresolvedMacroCall,
89 UnresolvedModule, UnresolvedProcMacro,
90 },
87 has_source::HasSource, 91 has_source::HasSource,
88 semantics::{PathResolution, Semantics, SemanticsScope}, 92 semantics::{PathResolution, Semantics, SemanticsScope},
89}; 93};
@@ -332,7 +336,7 @@ impl ModuleDef {
332 } 336 }
333 } 337 }
334 338
335 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { 339 pub fn diagnostics(self, db: &dyn HirDatabase) -> Vec<AnyDiagnostic> {
336 let id = match self { 340 let id = match self {
337 ModuleDef::Adt(it) => match it { 341 ModuleDef::Adt(it) => match it {
338 Adt::Struct(it) => it.id.into(), 342 Adt::Struct(it) => it.id.into(),
@@ -345,15 +349,19 @@ impl ModuleDef {
345 ModuleDef::Module(it) => it.id.into(), 349 ModuleDef::Module(it) => it.id.into(),
346 ModuleDef::Const(it) => it.id.into(), 350 ModuleDef::Const(it) => it.id.into(),
347 ModuleDef::Static(it) => it.id.into(), 351 ModuleDef::Static(it) => it.id.into(),
348 _ => return, 352 _ => return Vec::new(),
349 }; 353 };
350 354
351 let module = match self.module(db) { 355 let module = match self.module(db) {
352 Some(it) => it, 356 Some(it) => it,
353 None => return, 357 None => return Vec::new(),
354 }; 358 };
355 359
356 hir_ty::diagnostics::validate_module_item(db, module.id.krate(), id, sink) 360 let mut acc = Vec::new();
361 for diag in hir_ty::diagnostics::validate_module_item(db, module.id.krate(), id) {
362 acc.push(diag.into())
363 }
364 acc
357 } 365 }
358} 366}
359 367
@@ -442,10 +450,10 @@ impl Module {
442 } 450 }
443 451
444 pub fn visibility_of(self, db: &dyn HirDatabase, def: &ModuleDef) -> Option<Visibility> { 452 pub fn visibility_of(self, db: &dyn HirDatabase, def: &ModuleDef) -> Option<Visibility> {
445 self.id.def_map(db.upcast())[self.id.local_id].scope.visibility_of(def.clone().into()) 453 self.id.def_map(db.upcast())[self.id.local_id].scope.visibility_of((*def).into())
446 } 454 }
447 455
448 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { 456 pub fn diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>) {
449 let _p = profile::span("Module::diagnostics").detail(|| { 457 let _p = profile::span("Module::diagnostics").detail(|| {
450 format!("{:?}", self.name(db).map_or("<unknown>".into(), |name| name.to_string())) 458 format!("{:?}", self.name(db).map_or("<unknown>".into(), |name| name.to_string()))
451 }); 459 });
@@ -458,18 +466,22 @@ impl Module {
458 match &diag.kind { 466 match &diag.kind {
459 DefDiagnosticKind::UnresolvedModule { ast: declaration, candidate } => { 467 DefDiagnosticKind::UnresolvedModule { ast: declaration, candidate } => {
460 let decl = declaration.to_node(db.upcast()); 468 let decl = declaration.to_node(db.upcast());
461 sink.push(UnresolvedModule { 469 acc.push(
462 file: declaration.file_id, 470 UnresolvedModule {
463 decl: AstPtr::new(&decl), 471 decl: InFile::new(declaration.file_id, AstPtr::new(&decl)),
464 candidate: candidate.clone(), 472 candidate: candidate.clone(),
465 }) 473 }
474 .into(),
475 )
466 } 476 }
467 DefDiagnosticKind::UnresolvedExternCrate { ast } => { 477 DefDiagnosticKind::UnresolvedExternCrate { ast } => {
468 let item = ast.to_node(db.upcast()); 478 let item = ast.to_node(db.upcast());
469 sink.push(UnresolvedExternCrate { 479 acc.push(
470 file: ast.file_id, 480 UnresolvedExternCrate {
471 item: AstPtr::new(&item), 481 decl: InFile::new(ast.file_id, AstPtr::new(&item)),
472 }); 482 }
483 .into(),
484 );
473 } 485 }
474 486
475 DefDiagnosticKind::UnresolvedImport { id, index } => { 487 DefDiagnosticKind::UnresolvedImport { id, index } => {
@@ -478,25 +490,30 @@ impl Module {
478 let import = &item_tree[id.value]; 490 let import = &item_tree[id.value];
479 491
480 let use_tree = import.use_tree_to_ast(db.upcast(), file_id, *index); 492 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) }); 493 acc.push(
494 UnresolvedImport { decl: InFile::new(file_id, AstPtr::new(&use_tree)) }
495 .into(),
496 );
482 } 497 }
483 498
484 DefDiagnosticKind::UnconfiguredCode { ast, cfg, opts } => { 499 DefDiagnosticKind::UnconfiguredCode { ast, cfg, opts } => {
485 let item = ast.to_node(db.upcast()); 500 let item = ast.to_node(db.upcast());
486 sink.push(InactiveCode { 501 acc.push(
487 file: ast.file_id, 502 InactiveCode {
488 node: AstPtr::new(&item).into(), 503 node: ast.with_value(AstPtr::new(&item).into()),
489 cfg: cfg.clone(), 504 cfg: cfg.clone(),
490 opts: opts.clone(), 505 opts: opts.clone(),
491 }); 506 }
507 .into(),
508 );
492 } 509 }
493 510
494 DefDiagnosticKind::UnresolvedProcMacro { ast } => { 511 DefDiagnosticKind::UnresolvedProcMacro { ast } => {
495 let mut precise_location = None; 512 let mut precise_location = None;
496 let (file, ast, name) = match ast { 513 let (node, name) = match ast {
497 MacroCallKind::FnLike { ast_id, .. } => { 514 MacroCallKind::FnLike { ast_id, .. } => {
498 let node = ast_id.to_node(db.upcast()); 515 let node = ast_id.to_node(db.upcast());
499 (ast_id.file_id, SyntaxNodePtr::from(AstPtr::new(&node)), None) 516 (ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))), None)
500 } 517 }
501 MacroCallKind::Derive { ast_id, derive_name, .. } => { 518 MacroCallKind::Derive { ast_id, derive_name, .. } => {
502 let node = ast_id.to_node(db.upcast()); 519 let node = ast_id.to_node(db.upcast());
@@ -529,8 +546,7 @@ impl Module {
529 } 546 }
530 547
531 ( 548 (
532 ast_id.file_id, 549 ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))),
533 SyntaxNodePtr::from(AstPtr::new(&node)),
534 Some(derive_name.clone()), 550 Some(derive_name.clone()),
535 ) 551 )
536 } 552 }
@@ -541,73 +557,73 @@ impl Module {
541 || panic!("cannot find attribute #{}", invoc_attr_index), 557 || panic!("cannot find attribute #{}", invoc_attr_index),
542 ); 558 );
543 ( 559 (
544 ast_id.file_id, 560 ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&attr))),
545 SyntaxNodePtr::from(AstPtr::new(&attr)),
546 Some(attr_name.clone()), 561 Some(attr_name.clone()),
547 ) 562 )
548 } 563 }
549 }; 564 };
550 sink.push(UnresolvedProcMacro { 565 acc.push(
551 file, 566 UnresolvedProcMacro { node, precise_location, macro_name: name }.into(),
552 node: ast, 567 );
553 precise_location,
554 macro_name: name,
555 });
556 } 568 }
557 569
558 DefDiagnosticKind::UnresolvedMacroCall { ast, path } => { 570 DefDiagnosticKind::UnresolvedMacroCall { ast, path } => {
559 let node = ast.to_node(db.upcast()); 571 let node = ast.to_node(db.upcast());
560 sink.push(UnresolvedMacroCall { 572 acc.push(
561 file: ast.file_id, 573 UnresolvedMacroCall {
562 node: AstPtr::new(&node), 574 macro_call: InFile::new(ast.file_id, AstPtr::new(&node)),
563 path: path.clone(), 575 path: path.clone(),
564 }); 576 }
577 .into(),
578 );
565 } 579 }
566 580
567 DefDiagnosticKind::MacroError { ast, message } => { 581 DefDiagnosticKind::MacroError { ast, message } => {
568 let (file, ast) = match ast { 582 let node = match ast {
569 MacroCallKind::FnLike { ast_id, .. } => { 583 MacroCallKind::FnLike { ast_id, .. } => {
570 let node = ast_id.to_node(db.upcast()); 584 let node = ast_id.to_node(db.upcast());
571 (ast_id.file_id, SyntaxNodePtr::from(AstPtr::new(&node))) 585 ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node)))
572 } 586 }
573 MacroCallKind::Derive { ast_id, .. } 587 MacroCallKind::Derive { ast_id, .. }
574 | MacroCallKind::Attr { ast_id, .. } => { 588 | MacroCallKind::Attr { ast_id, .. } => {
575 // FIXME: point to the attribute instead, this creates very large diagnostics 589 // FIXME: point to the attribute instead, this creates very large diagnostics
576 let node = ast_id.to_node(db.upcast()); 590 let node = ast_id.to_node(db.upcast());
577 (ast_id.file_id, SyntaxNodePtr::from(AstPtr::new(&node))) 591 ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node)))
578 } 592 }
579 }; 593 };
580 sink.push(MacroError { file, node: ast, message: message.clone() }); 594 acc.push(MacroError { node, message: message.clone() }.into());
581 } 595 }
582 596
583 DefDiagnosticKind::UnimplementedBuiltinMacro { ast } => { 597 DefDiagnosticKind::UnimplementedBuiltinMacro { ast } => {
584 let node = ast.to_node(db.upcast()); 598 let node = ast.to_node(db.upcast());
585 // Must have a name, otherwise we wouldn't emit it. 599 // Must have a name, otherwise we wouldn't emit it.
586 let name = node.name().expect("unimplemented builtin macro with no name"); 600 let name = node.name().expect("unimplemented builtin macro with no name");
587 let ptr = SyntaxNodePtr::from(AstPtr::new(&name)); 601 acc.push(
588 sink.push(UnimplementedBuiltinMacro { file: ast.file_id, node: ptr }); 602 UnimplementedBuiltinMacro {
603 node: ast.with_value(SyntaxNodePtr::from(AstPtr::new(&name))),
604 }
605 .into(),
606 );
589 } 607 }
590 } 608 }
591 } 609 }
592 for decl in self.declarations(db) { 610 for decl in self.declarations(db) {
593 match decl { 611 match decl {
594 crate::ModuleDef::Function(f) => f.diagnostics(db, sink), 612 ModuleDef::Function(f) => f.diagnostics(db, acc),
595 crate::ModuleDef::Module(m) => { 613 ModuleDef::Module(m) => {
596 // Only add diagnostics from inline modules 614 // Only add diagnostics from inline modules
597 if def_map[m.id.local_id].origin.is_inline() { 615 if def_map[m.id.local_id].origin.is_inline() {
598 m.diagnostics(db, sink) 616 m.diagnostics(db, acc)
599 } 617 }
600 } 618 }
601 _ => { 619 _ => acc.extend(decl.diagnostics(db)),
602 decl.diagnostics(db, sink);
603 }
604 } 620 }
605 } 621 }
606 622
607 for impl_def in self.impl_defs(db) { 623 for impl_def in self.impl_defs(db) {
608 for item in impl_def.items(db) { 624 for item in impl_def.items(db) {
609 if let AssocItem::Function(f) = item { 625 if let AssocItem::Function(f) = item {
610 f.diagnostics(db, sink); 626 f.diagnostics(db, acc);
611 } 627 }
612 } 628 }
613 } 629 }
@@ -1009,41 +1025,191 @@ impl Function {
1009 db.function_data(self.id).is_async() 1025 db.function_data(self.id).is_async()
1010 } 1026 }
1011 1027
1012 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { 1028 pub fn diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>) {
1013 let krate = self.module(db).id.krate(); 1029 let krate = self.module(db).id.krate();
1014 1030
1015 let source_map = db.body_with_source_map(self.id.into()).1; 1031 let source_map = db.body_with_source_map(self.id.into()).1;
1016 for diag in source_map.diagnostics() { 1032 for diag in source_map.diagnostics() {
1017 match diag { 1033 match diag {
1018 BodyDiagnostic::InactiveCode { node, cfg, opts } => sink.push(InactiveCode { 1034 BodyDiagnostic::InactiveCode { node, cfg, opts } => acc.push(
1019 file: node.file_id, 1035 InactiveCode { node: node.clone(), cfg: cfg.clone(), opts: opts.clone() }
1020 node: node.value.clone(), 1036 .into(),
1021 cfg: cfg.clone(), 1037 ),
1022 opts: opts.clone(), 1038 BodyDiagnostic::MacroError { node, message } => acc.push(
1023 }), 1039 MacroError {
1024 BodyDiagnostic::MacroError { node, message } => sink.push(MacroError { 1040 node: node.clone().map(|it| it.into()),
1025 file: node.file_id, 1041 message: message.to_string(),
1026 node: node.value.clone().into(), 1042 }
1027 message: message.to_string(), 1043 .into(),
1028 }), 1044 ),
1029 BodyDiagnostic::UnresolvedProcMacro { node } => sink.push(UnresolvedProcMacro { 1045 BodyDiagnostic::UnresolvedProcMacro { node } => acc.push(
1030 file: node.file_id, 1046 UnresolvedProcMacro {
1031 node: node.value.clone().into(), 1047 node: node.clone().map(|it| it.into()),
1032 precise_location: None, 1048 precise_location: None,
1033 macro_name: None, 1049 macro_name: None,
1034 }), 1050 }
1035 BodyDiagnostic::UnresolvedMacroCall { node, path } => { 1051 .into(),
1036 sink.push(UnresolvedMacroCall { 1052 ),
1037 file: node.file_id, 1053 BodyDiagnostic::UnresolvedMacroCall { node, path } => acc.push(
1038 node: node.value.clone(), 1054 UnresolvedMacroCall { macro_call: node.clone(), path: path.clone() }.into(),
1039 path: path.clone(), 1055 ),
1040 }) 1056 }
1057 }
1058
1059 let infer = db.infer(self.id.into());
1060 let source_map = Lazy::new(|| db.body_with_source_map(self.id.into()).1);
1061 for d in &infer.diagnostics {
1062 match d {
1063 hir_ty::InferenceDiagnostic::NoSuchField { expr } => {
1064 let field = source_map.field_syntax(*expr);
1065 acc.push(NoSuchField { field }.into())
1066 }
1067 hir_ty::InferenceDiagnostic::BreakOutsideOfLoop { expr } => {
1068 let expr = source_map
1069 .expr_syntax(*expr)
1070 .expect("break outside of loop in synthetic syntax");
1071 acc.push(BreakOutsideOfLoop { expr }.into())
1041 } 1072 }
1042 } 1073 }
1043 } 1074 }
1044 1075
1045 hir_ty::diagnostics::validate_module_item(db, krate, self.id.into(), sink); 1076 for expr in hir_ty::diagnostics::missing_unsafe(db, self.id.into()) {
1046 hir_ty::diagnostics::validate_body(db, self.id.into(), sink); 1077 match source_map.expr_syntax(expr) {
1078 Ok(expr) => acc.push(MissingUnsafe { expr }.into()),
1079 Err(SyntheticSyntax) => {
1080 // FIXME: Here and eslwhere in this file, the `expr` was
1081 // desugared, report or assert that this doesn't happen.
1082 }
1083 }
1084 }
1085
1086 for diagnostic in BodyValidationDiagnostic::collect(db, self.id.into()) {
1087 match diagnostic {
1088 BodyValidationDiagnostic::RecordMissingFields {
1089 record,
1090 variant,
1091 missed_fields,
1092 } => {
1093 let variant_data = variant.variant_data(db.upcast());
1094 let missed_fields = missed_fields
1095 .into_iter()
1096 .map(|idx| variant_data.fields()[idx].name.clone())
1097 .collect();
1098
1099 match record {
1100 Either::Left(record_expr) => match source_map.expr_syntax(record_expr) {
1101 Ok(source_ptr) => {
1102 let root = source_ptr.file_syntax(db.upcast());
1103 if let ast::Expr::RecordExpr(record_expr) =
1104 &source_ptr.value.to_node(&root)
1105 {
1106 if let Some(_) = record_expr.record_expr_field_list() {
1107 acc.push(
1108 MissingFields {
1109 file: source_ptr.file_id,
1110 field_list_parent: Either::Left(AstPtr::new(
1111 record_expr,
1112 )),
1113 field_list_parent_path: record_expr
1114 .path()
1115 .map(|path| AstPtr::new(&path)),
1116 missed_fields,
1117 }
1118 .into(),
1119 )
1120 }
1121 }
1122 }
1123 Err(SyntheticSyntax) => (),
1124 },
1125 Either::Right(record_pat) => match source_map.pat_syntax(record_pat) {
1126 Ok(source_ptr) => {
1127 if let Some(expr) = source_ptr.value.as_ref().left() {
1128 let root = source_ptr.file_syntax(db.upcast());
1129 if let ast::Pat::RecordPat(record_pat) = expr.to_node(&root) {
1130 if let Some(_) = record_pat.record_pat_field_list() {
1131 acc.push(
1132 MissingFields {
1133 file: source_ptr.file_id,
1134 field_list_parent: Either::Right(AstPtr::new(
1135 &record_pat,
1136 )),
1137 field_list_parent_path: record_pat
1138 .path()
1139 .map(|path| AstPtr::new(&path)),
1140 missed_fields,
1141 }
1142 .into(),
1143 )
1144 }
1145 }
1146 }
1147 }
1148 Err(SyntheticSyntax) => (),
1149 },
1150 }
1151 }
1152 BodyValidationDiagnostic::ReplaceFilterMapNextWithFindMap { method_call_expr } => {
1153 if let Ok(next_source_ptr) = source_map.expr_syntax(method_call_expr) {
1154 acc.push(
1155 ReplaceFilterMapNextWithFindMap {
1156 file: next_source_ptr.file_id,
1157 next_expr: next_source_ptr.value,
1158 }
1159 .into(),
1160 );
1161 }
1162 }
1163 BodyValidationDiagnostic::MismatchedArgCount { call_expr, expected, found } => {
1164 match source_map.expr_syntax(call_expr) {
1165 Ok(source_ptr) => acc.push(
1166 MismatchedArgCount { call_expr: source_ptr, expected, found }.into(),
1167 ),
1168 Err(SyntheticSyntax) => (),
1169 }
1170 }
1171 BodyValidationDiagnostic::RemoveThisSemicolon { expr } => {
1172 match source_map.expr_syntax(expr) {
1173 Ok(expr) => acc.push(RemoveThisSemicolon { expr }.into()),
1174 Err(SyntheticSyntax) => (),
1175 }
1176 }
1177 BodyValidationDiagnostic::MissingOkOrSomeInTailExpr { expr, required } => {
1178 match source_map.expr_syntax(expr) {
1179 Ok(expr) => acc.push(MissingOkOrSomeInTailExpr { expr, required }.into()),
1180 Err(SyntheticSyntax) => (),
1181 }
1182 }
1183 BodyValidationDiagnostic::MissingMatchArms { match_expr } => {
1184 match source_map.expr_syntax(match_expr) {
1185 Ok(source_ptr) => {
1186 let root = source_ptr.file_syntax(db.upcast());
1187 if let ast::Expr::MatchExpr(match_expr) =
1188 &source_ptr.value.to_node(&root)
1189 {
1190 if let (Some(match_expr), Some(arms)) =
1191 (match_expr.expr(), match_expr.match_arm_list())
1192 {
1193 acc.push(
1194 MissingMatchArms {
1195 file: source_ptr.file_id,
1196 match_expr: AstPtr::new(&match_expr),
1197 arms: AstPtr::new(&arms),
1198 }
1199 .into(),
1200 )
1201 }
1202 }
1203 }
1204 Err(SyntheticSyntax) => (),
1205 }
1206 }
1207 }
1208 }
1209
1210 for diag in hir_ty::diagnostics::validate_module_item(db, krate, self.id.into()) {
1211 acc.push(diag.into())
1212 }
1047 } 1213 }
1048 1214
1049 /// Whether this function declaration has a definition. 1215 /// Whether this function declaration has a definition.
@@ -1762,7 +1928,7 @@ impl Impl {
1762 } 1928 }
1763 1929
1764 pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> { 1930 pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> {
1765 let def_crates = match def_crates(db, &ty, krate) { 1931 let def_crates = match method_resolution::def_crates(db, &ty, krate) {
1766 Some(def_crates) => def_crates, 1932 Some(def_crates) => def_crates,
1767 None => return Vec::new(), 1933 None => return Vec::new(),
1768 }; 1934 };
@@ -2168,7 +2334,7 @@ impl Type {
2168 krate: Crate, 2334 krate: Crate,
2169 mut callback: impl FnMut(AssocItem) -> Option<T>, 2335 mut callback: impl FnMut(AssocItem) -> Option<T>,
2170 ) -> Option<T> { 2336 ) -> Option<T> {
2171 for krate in def_crates(db, &self.ty, krate.id)? { 2337 for krate in method_resolution::def_crates(db, &self.ty, krate.id)? {
2172 let impls = db.inherent_impls_in_crate(krate); 2338 let impls = db.inherent_impls_in_crate(krate);
2173 2339
2174 for impl_def in impls.for_self_ty(&self.ty) { 2340 for impl_def in impls.for_self_ty(&self.ty) {
@@ -2345,13 +2511,13 @@ impl Type {
2345 match ty.kind(&Interner) { 2511 match ty.kind(&Interner) {
2346 TyKind::Adt(_, substs) => { 2512 TyKind::Adt(_, substs) => {
2347 cb(type_.derived(ty.clone())); 2513 cb(type_.derived(ty.clone()));
2348 walk_substs(db, type_, &substs, cb); 2514 walk_substs(db, type_, substs, cb);
2349 } 2515 }
2350 TyKind::AssociatedType(_, substs) => { 2516 TyKind::AssociatedType(_, substs) => {
2351 if let Some(_) = ty.associated_type_parent_trait(db) { 2517 if let Some(_) = ty.associated_type_parent_trait(db) {
2352 cb(type_.derived(ty.clone())); 2518 cb(type_.derived(ty.clone()));
2353 } 2519 }
2354 walk_substs(db, type_, &substs, cb); 2520 walk_substs(db, type_, substs, cb);
2355 } 2521 }
2356 TyKind::OpaqueType(_, subst) => { 2522 TyKind::OpaqueType(_, subst) => {
2357 if let Some(bounds) = ty.impl_trait_bounds(db) { 2523 if let Some(bounds) = ty.impl_trait_bounds(db) {
@@ -2391,7 +2557,7 @@ impl Type {
2391 TyKind::FnDef(_, substs) 2557 TyKind::FnDef(_, substs)
2392 | TyKind::Tuple(_, substs) 2558 | TyKind::Tuple(_, substs)
2393 | TyKind::Closure(.., substs) => { 2559 | TyKind::Closure(.., substs) => {
2394 walk_substs(db, type_, &substs, cb); 2560 walk_substs(db, type_, substs, cb);
2395 } 2561 }
2396 TyKind::Function(hir_ty::FnPointer { substitution, .. }) => { 2562 TyKind::Function(hir_ty::FnPointer { substitution, .. }) => {
2397 walk_substs(db, type_, &substitution.0, cb); 2563 walk_substs(db, type_, &substitution.0, cb);
@@ -2522,18 +2688,6 @@ impl ScopeDef {
2522 2688
2523 items 2689 items
2524 } 2690 }
2525
2526 pub fn is_value_def(&self) -> bool {
2527 matches!(
2528 self,
2529 ScopeDef::ModuleDef(ModuleDef::Function(_))
2530 | ScopeDef::ModuleDef(ModuleDef::Variant(_))
2531 | ScopeDef::ModuleDef(ModuleDef::Const(_))
2532 | ScopeDef::ModuleDef(ModuleDef::Static(_))
2533 | ScopeDef::GenericParam(GenericParam::ConstParam(_))
2534 | ScopeDef::Local(_)
2535 )
2536 }
2537} 2691}
2538 2692
2539impl From<ItemInNs> for ScopeDef { 2693impl From<ItemInNs> for ScopeDef {