@@ -347,12 +347,36 @@ impl ModuleDef {
347347 } ;
348348
349349 let mut acc = Vec :: new ( ) ;
350- for diag in hir_ty:: diagnostics:: validate_module_item ( db, module. id . krate ( ) , id) {
351- acc. push ( diag. into ( ) )
350+
351+ match self . as_def_with_body ( ) {
352+ Some ( def) => {
353+ def. diagnostics ( db, & mut acc) ;
354+ }
355+ None => {
356+ for diag in hir_ty:: diagnostics:: validate_module_item ( db, module. id . krate ( ) , id) {
357+ acc. push ( diag. into ( ) )
358+ }
359+ }
352360 }
361+
353362 acc
354363 }
355364
365+ pub fn as_def_with_body ( self ) -> Option < DefWithBody > {
366+ match self {
367+ ModuleDef :: Function ( it) => Some ( it. into ( ) ) ,
368+ ModuleDef :: Const ( it) => Some ( it. into ( ) ) ,
369+ ModuleDef :: Static ( it) => Some ( it. into ( ) ) ,
370+
371+ ModuleDef :: Module ( _)
372+ | ModuleDef :: Adt ( _)
373+ | ModuleDef :: Variant ( _)
374+ | ModuleDef :: Trait ( _)
375+ | ModuleDef :: TypeAlias ( _)
376+ | ModuleDef :: BuiltinType ( _) => None ,
377+ }
378+ }
379+
356380 pub fn attrs ( & self , db : & dyn HirDatabase ) -> Option < AttrsWithOwner > {
357381 Some ( match self {
358382 ModuleDef :: Module ( it) => it. attrs ( db) ,
@@ -624,7 +648,6 @@ impl Module {
624648 }
625649 for decl in self . declarations ( db) {
626650 match decl {
627- ModuleDef :: Function ( f) => f. diagnostics ( db, acc) ,
628651 ModuleDef :: Module ( m) => {
629652 // Only add diagnostics from inline modules
630653 if def_map[ m. id . local_id ] . origin . is_inline ( ) {
@@ -637,9 +660,13 @@ impl Module {
637660
638661 for impl_def in self . impl_defs ( db) {
639662 for item in impl_def. items ( db) {
640- if let AssocItem :: Function ( f) = item {
641- f. diagnostics ( db, acc) ;
642- }
663+ let def: DefWithBody = match item {
664+ AssocItem :: Function ( it) => it. into ( ) ,
665+ AssocItem :: Const ( it) => it. into ( ) ,
666+ AssocItem :: TypeAlias ( _) => continue ,
667+ } ;
668+
669+ def. diagnostics ( db, acc) ;
643670 }
644671 }
645672 }
@@ -999,76 +1026,20 @@ impl DefWithBody {
9991026 DefWithBody :: Const ( c) => c. name ( db) ,
10001027 }
10011028 }
1002- }
1003-
1004- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
1005- pub struct Function {
1006- pub ( crate ) id : FunctionId ,
1007- }
1008-
1009- impl Function {
1010- pub fn module ( self , db : & dyn HirDatabase ) -> Module {
1011- self . id . lookup ( db. upcast ( ) ) . module ( db. upcast ( ) ) . into ( )
1012- }
1013-
1014- pub fn name ( self , db : & dyn HirDatabase ) -> Name {
1015- db. function_data ( self . id ) . name . clone ( )
1016- }
10171029
1018- /// Get this function's return type
1019- pub fn ret_type ( self , db : & dyn HirDatabase ) -> Type {
1020- let resolver = self . id . resolver ( db. upcast ( ) ) ;
1021- let krate = self . id . lookup ( db. upcast ( ) ) . container . module ( db. upcast ( ) ) . krate ( ) ;
1022- let ret_type = & db. function_data ( self . id ) . ret_type ;
1023- let ctx = hir_ty:: TyLoweringContext :: new ( db, & resolver) ;
1024- let ty = ctx. lower_ty ( ret_type) ;
1025- Type :: new_with_resolver_inner ( db, krate, & resolver, ty)
1026- }
1027-
1028- pub fn self_param ( self , db : & dyn HirDatabase ) -> Option < SelfParam > {
1029- if !db. function_data ( self . id ) . has_self_param ( ) {
1030- return None ;
1031- }
1032- Some ( SelfParam { func : self . id } )
1033- }
1034-
1035- pub fn assoc_fn_params ( self , db : & dyn HirDatabase ) -> Vec < Param > {
1036- let resolver = self . id . resolver ( db. upcast ( ) ) ;
1037- let krate = self . id . lookup ( db. upcast ( ) ) . container . module ( db. upcast ( ) ) . krate ( ) ;
1038- let ctx = hir_ty:: TyLoweringContext :: new ( db, & resolver) ;
1039- let environment = db. trait_environment ( self . id . into ( ) ) ;
1040- db. function_data ( self . id )
1041- . params
1042- . iter ( )
1043- . enumerate ( )
1044- . map ( |( idx, type_ref) | {
1045- let ty = Type { krate, env : environment. clone ( ) , ty : ctx. lower_ty ( type_ref) } ;
1046- Param { func : self , ty, idx }
1047- } )
1048- . collect ( )
1049- }
1050-
1051- pub fn method_params ( self , db : & dyn HirDatabase ) -> Option < Vec < Param > > {
1052- if self . self_param ( db) . is_none ( ) {
1053- return None ;
1030+ /// Returns the type this def's body has to evaluate to.
1031+ pub fn body_type ( self , db : & dyn HirDatabase ) -> Type {
1032+ match self {
1033+ DefWithBody :: Function ( it) => it. ret_type ( db) ,
1034+ DefWithBody :: Static ( it) => it. ty ( db) ,
1035+ DefWithBody :: Const ( it) => it. ty ( db) ,
10541036 }
1055- let mut res = self . assoc_fn_params ( db) ;
1056- res. remove ( 0 ) ;
1057- Some ( res)
1058- }
1059-
1060- pub fn is_unsafe ( self , db : & dyn HirDatabase ) -> bool {
1061- db. function_data ( self . id ) . is_unsafe ( )
1062- }
1063-
1064- pub fn is_async ( self , db : & dyn HirDatabase ) -> bool {
1065- db. function_data ( self . id ) . is_async ( )
10661037 }
10671038
10681039 pub fn diagnostics ( self , db : & dyn HirDatabase , acc : & mut Vec < AnyDiagnostic > ) {
10691040 let krate = self . module ( db) . id . krate ( ) ;
10701041
1071- let source_map = db. body_with_source_map ( self . id . into ( ) ) . 1 ;
1042+ let source_map = db. body_with_source_map ( self . into ( ) ) . 1 ;
10721043 for diag in source_map. diagnostics ( ) {
10731044 match diag {
10741045 BodyDiagnostic :: InactiveCode { node, cfg, opts } => acc. push (
@@ -1096,8 +1067,8 @@ impl Function {
10961067 }
10971068 }
10981069
1099- let infer = db. infer ( self . id . into ( ) ) ;
1100- let source_map = Lazy :: new ( || db. body_with_source_map ( self . id . into ( ) ) . 1 ) ;
1070+ let infer = db. infer ( self . into ( ) ) ;
1071+ let source_map = Lazy :: new ( || db. body_with_source_map ( self . into ( ) ) . 1 ) ;
11011072 for d in & infer. diagnostics {
11021073 match d {
11031074 hir_ty:: InferenceDiagnostic :: NoSuchField { expr } => {
@@ -1113,7 +1084,7 @@ impl Function {
11131084 }
11141085 }
11151086
1116- for expr in hir_ty:: diagnostics:: missing_unsafe ( db, self . id . into ( ) ) {
1087+ for expr in hir_ty:: diagnostics:: missing_unsafe ( db, self . into ( ) ) {
11171088 match source_map. expr_syntax ( expr) {
11181089 Ok ( expr) => acc. push ( MissingUnsafe { expr } . into ( ) ) ,
11191090 Err ( SyntheticSyntax ) => {
@@ -1123,7 +1094,7 @@ impl Function {
11231094 }
11241095 }
11251096
1126- for diagnostic in BodyValidationDiagnostic :: collect ( db, self . id . into ( ) ) {
1097+ for diagnostic in BodyValidationDiagnostic :: collect ( db, self . into ( ) ) {
11271098 match diagnostic {
11281099 BodyValidationDiagnostic :: RecordMissingFields {
11291100 record,
@@ -1220,7 +1191,7 @@ impl Function {
12201191 MissingOkOrSomeInTailExpr {
12211192 expr,
12221193 required,
1223- expected : self . ret_type ( db) ,
1194+ expected : self . body_type ( db) ,
12241195 }
12251196 . into ( ) ,
12261197 ) ,
@@ -1260,10 +1231,80 @@ impl Function {
12601231 }
12611232 }
12621233
1263- for diag in hir_ty:: diagnostics:: validate_module_item ( db, krate, self . id . into ( ) ) {
1234+ let def: ModuleDef = match self {
1235+ DefWithBody :: Function ( it) => it. into ( ) ,
1236+ DefWithBody :: Static ( it) => it. into ( ) ,
1237+ DefWithBody :: Const ( it) => it. into ( ) ,
1238+ } ;
1239+ for diag in hir_ty:: diagnostics:: validate_module_item ( db, krate, def. into ( ) ) {
12641240 acc. push ( diag. into ( ) )
12651241 }
12661242 }
1243+ }
1244+
1245+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
1246+ pub struct Function {
1247+ pub ( crate ) id : FunctionId ,
1248+ }
1249+
1250+ impl Function {
1251+ pub fn module ( self , db : & dyn HirDatabase ) -> Module {
1252+ self . id . lookup ( db. upcast ( ) ) . module ( db. upcast ( ) ) . into ( )
1253+ }
1254+
1255+ pub fn name ( self , db : & dyn HirDatabase ) -> Name {
1256+ db. function_data ( self . id ) . name . clone ( )
1257+ }
1258+
1259+ /// Get this function's return type
1260+ pub fn ret_type ( self , db : & dyn HirDatabase ) -> Type {
1261+ let resolver = self . id . resolver ( db. upcast ( ) ) ;
1262+ let krate = self . id . lookup ( db. upcast ( ) ) . container . module ( db. upcast ( ) ) . krate ( ) ;
1263+ let ret_type = & db. function_data ( self . id ) . ret_type ;
1264+ let ctx = hir_ty:: TyLoweringContext :: new ( db, & resolver) ;
1265+ let ty = ctx. lower_ty ( ret_type) ;
1266+ Type :: new_with_resolver_inner ( db, krate, & resolver, ty)
1267+ }
1268+
1269+ pub fn self_param ( self , db : & dyn HirDatabase ) -> Option < SelfParam > {
1270+ if !db. function_data ( self . id ) . has_self_param ( ) {
1271+ return None ;
1272+ }
1273+ Some ( SelfParam { func : self . id } )
1274+ }
1275+
1276+ pub fn assoc_fn_params ( self , db : & dyn HirDatabase ) -> Vec < Param > {
1277+ let resolver = self . id . resolver ( db. upcast ( ) ) ;
1278+ let krate = self . id . lookup ( db. upcast ( ) ) . container . module ( db. upcast ( ) ) . krate ( ) ;
1279+ let ctx = hir_ty:: TyLoweringContext :: new ( db, & resolver) ;
1280+ let environment = db. trait_environment ( self . id . into ( ) ) ;
1281+ db. function_data ( self . id )
1282+ . params
1283+ . iter ( )
1284+ . enumerate ( )
1285+ . map ( |( idx, type_ref) | {
1286+ let ty = Type { krate, env : environment. clone ( ) , ty : ctx. lower_ty ( type_ref) } ;
1287+ Param { func : self , ty, idx }
1288+ } )
1289+ . collect ( )
1290+ }
1291+
1292+ pub fn method_params ( self , db : & dyn HirDatabase ) -> Option < Vec < Param > > {
1293+ if self . self_param ( db) . is_none ( ) {
1294+ return None ;
1295+ }
1296+ let mut res = self . assoc_fn_params ( db) ;
1297+ res. remove ( 0 ) ;
1298+ Some ( res)
1299+ }
1300+
1301+ pub fn is_unsafe ( self , db : & dyn HirDatabase ) -> bool {
1302+ db. function_data ( self . id ) . is_unsafe ( )
1303+ }
1304+
1305+ pub fn is_async ( self , db : & dyn HirDatabase ) -> bool {
1306+ db. function_data ( self . id ) . is_async ( )
1307+ }
12671308
12681309 /// Whether this function declaration has a definition.
12691310 ///
0 commit comments