33pub ( crate ) use gen_trait_fn_body:: gen_trait_fn_body;
44use hir:: {
55 db:: { ExpandDatabase , HirDatabase } ,
6- HasAttrs as HirHasAttrs , HirDisplay , InFile , Semantics ,
6+ HasAttrs as HirHasAttrs , HirDisplay , InFile , ModuleDef , PathResolution , Semantics ,
77} ;
88use ide_db:: {
9- famous_defs:: FamousDefs , path_transform:: PathTransform ,
10- syntax_helpers:: prettify_macro_expansion, RootDatabase ,
9+ famous_defs:: FamousDefs ,
10+ path_transform:: PathTransform ,
11+ syntax_helpers:: { node_ext:: preorder_expr, prettify_macro_expansion} ,
12+ RootDatabase ,
1113} ;
1214use stdx:: format_to;
1315use syntax:: {
@@ -19,7 +21,7 @@ use syntax::{
1921 } ,
2022 ted, AstNode , AstToken , Direction , Edition , NodeOrToken , SourceFile ,
2123 SyntaxKind :: * ,
22- SyntaxNode , SyntaxToken , TextRange , TextSize , T ,
24+ SyntaxNode , SyntaxToken , TextRange , TextSize , WalkEvent , T ,
2325} ;
2426
2527use crate :: assist_context:: { AssistContext , SourceChangeBuilder } ;
@@ -966,3 +968,37 @@ pub(crate) fn tt_from_syntax(node: SyntaxNode) -> Vec<NodeOrToken<ast::TokenTree
966968
967969 tt_stack. pop ( ) . expect ( "parent token tree was closed before it was completed" ) . 1
968970}
971+
972+ pub fn is_body_const ( sema : & Semantics < ' _ , RootDatabase > , expr : & ast:: Expr ) -> bool {
973+ let mut is_const = true ;
974+ preorder_expr ( expr, & mut |ev| {
975+ let expr = match ev {
976+ WalkEvent :: Enter ( _) if !is_const => return true ,
977+ WalkEvent :: Enter ( expr) => expr,
978+ WalkEvent :: Leave ( _) => return false ,
979+ } ;
980+ match expr {
981+ ast:: Expr :: CallExpr ( call) => {
982+ if let Some ( ast:: Expr :: PathExpr ( path_expr) ) = call. expr ( ) {
983+ if let Some ( PathResolution :: Def ( ModuleDef :: Function ( func) ) ) =
984+ path_expr. path ( ) . and_then ( |path| sema. resolve_path ( & path) )
985+ {
986+ is_const &= func. is_const ( sema. db ) ;
987+ }
988+ }
989+ }
990+ ast:: Expr :: MethodCallExpr ( call) => {
991+ is_const &=
992+ sema. resolve_method_call ( & call) . map ( |it| it. is_const ( sema. db ) ) . unwrap_or ( true )
993+ }
994+ ast:: Expr :: ForExpr ( _)
995+ | ast:: Expr :: ReturnExpr ( _)
996+ | ast:: Expr :: TryExpr ( _)
997+ | ast:: Expr :: YieldExpr ( _)
998+ | ast:: Expr :: AwaitExpr ( _) => is_const = false ,
999+ _ => ( ) ,
1000+ }
1001+ !is_const
1002+ } ) ;
1003+ is_const
1004+ }
0 commit comments