77// These fields are better explicit than .. since we are forced to consider if new fields should be searched
88#![ allow( clippy:: unneeded_field_pattern) ]
99
10+ use super :: named_entity:: TypeEnt ;
1011use super :: * ;
1112use crate :: ast:: * ;
1213use crate :: data:: * ;
@@ -18,6 +19,7 @@ impl<'a> AnalyzeContext<'a> {
1819 fn analyze_sequential_statement (
1920 & self ,
2021 scope : & Scope < ' a > ,
22+ sroot : & SequentialRoot < ' a > ,
2123 statement : & mut LabeledSequentialStatement ,
2224 diagnostics : & mut dyn DiagnosticHandler ,
2325 ) -> FatalResult {
@@ -27,9 +29,29 @@ impl<'a> AnalyzeContext<'a> {
2729
2830 match statement. statement {
2931 SequentialStatement :: Return ( ref mut ret) => {
30- let ReturnStatement { expression } = ret;
31- if let Some ( ref mut expression) = expression {
32- self . analyze_expression ( scope, expression, diagnostics) ?;
32+ let ReturnStatement { ref mut expression } = ret. item ;
33+
34+ match sroot {
35+ SequentialRoot :: Function ( ttyp) => {
36+ if let Some ( ref mut expression) = expression {
37+ self . expr_with_ttyp ( scope, * ttyp, expression, diagnostics) ?;
38+ } else {
39+ diagnostics. error ( & ret. pos , "Functions cannot return without a value" ) ;
40+ }
41+ }
42+ SequentialRoot :: Procedure => {
43+ if expression. is_some ( ) {
44+ diagnostics. error ( & ret. pos , "Procedures cannot return a value" ) ;
45+ }
46+ }
47+ SequentialRoot :: Process => {
48+ diagnostics. error ( & ret. pos , "Cannot return from a process" ) ;
49+ }
50+ SequentialRoot :: Unknown => {
51+ if let Some ( ref mut expression) = expression {
52+ self . analyze_expression ( scope, expression, diagnostics) ?;
53+ }
54+ }
3355 }
3456 }
3557 SequentialStatement :: Wait ( ref mut wait_stmt) => {
@@ -98,11 +120,11 @@ impl<'a> AnalyzeContext<'a> {
98120 // @TODO write generic function for this
99121 for conditional in conditionals {
100122 let Conditional { condition, item } = conditional;
101- self . analyze_sequential_part ( scope, item, diagnostics) ?;
123+ self . analyze_sequential_part ( scope, sroot , item, diagnostics) ?;
102124 self . analyze_expression ( scope, condition, diagnostics) ?;
103125 }
104126 if let Some ( else_item) = else_item {
105- self . analyze_sequential_part ( scope, else_item, diagnostics) ?;
127+ self . analyze_sequential_part ( scope, sroot , else_item, diagnostics) ?;
106128 }
107129 }
108130 SequentialStatement :: Case ( ref mut case_stmt) => {
@@ -115,7 +137,7 @@ impl<'a> AnalyzeContext<'a> {
115137 for alternative in alternatives. iter_mut ( ) {
116138 let Alternative { choices, item } = alternative;
117139 self . analyze_choices ( scope, choices, diagnostics) ?;
118- self . analyze_sequential_part ( scope, item, diagnostics) ?;
140+ self . analyze_sequential_part ( scope, sroot , item, diagnostics) ?;
119141 }
120142 }
121143 SequentialStatement :: Loop ( ref mut loop_stmt) => {
@@ -131,14 +153,14 @@ impl<'a> AnalyzeContext<'a> {
131153 self . arena . define ( index, AnyEntKind :: LoopParameter ( typ) ) ,
132154 diagnostics,
133155 ) ;
134- self . analyze_sequential_part ( & region, statements, diagnostics) ?;
156+ self . analyze_sequential_part ( & region, sroot , statements, diagnostics) ?;
135157 }
136158 Some ( IterationScheme :: While ( ref mut expr) ) => {
137159 self . analyze_expression ( scope, expr, diagnostics) ?;
138- self . analyze_sequential_part ( scope, statements, diagnostics) ?;
160+ self . analyze_sequential_part ( scope, sroot , statements, diagnostics) ?;
139161 }
140162 None => {
141- self . analyze_sequential_part ( scope, statements, diagnostics) ?;
163+ self . analyze_sequential_part ( scope, sroot , statements, diagnostics) ?;
142164 }
143165 }
144166 }
@@ -195,13 +217,21 @@ impl<'a> AnalyzeContext<'a> {
195217 pub fn analyze_sequential_part (
196218 & self ,
197219 scope : & Scope < ' a > ,
220+ sroot : & SequentialRoot < ' a > ,
198221 statements : & mut [ LabeledSequentialStatement ] ,
199222 diagnostics : & mut dyn DiagnosticHandler ,
200223 ) -> FatalResult {
201224 for statement in statements. iter_mut ( ) {
202- self . analyze_sequential_statement ( scope, statement, diagnostics) ?;
225+ self . analyze_sequential_statement ( scope, sroot , statement, diagnostics) ?;
203226 }
204227
205228 Ok ( ( ) )
206229 }
207230}
231+
232+ pub enum SequentialRoot < ' a > {
233+ Process ,
234+ Procedure ,
235+ Function ( TypeEnt < ' a > ) ,
236+ Unknown ,
237+ }
0 commit comments