@@ -4,7 +4,7 @@ use crate::checks;
44use crate :: diagnostic:: { Diagnostic , code} ;
55use crate :: hir:: { DuplicateSymbolKind , Hir , HirTypeKind } ;
66use crate :: lexer:: { Token , lex} ;
7- use crate :: syntax:: ast:: { Callee , EffectDecl , Expr , Item , Stmt , TypeRef } ;
7+ use crate :: syntax:: ast:: { Callee , DataEffect , EffectDecl , Expr , Item , Stmt , TypeRef } ;
88use crate :: syntax:: parse_source;
99
1010pub fn analyze_source ( file : & str , source : & str ) -> Vec < Diagnostic > {
@@ -187,6 +187,60 @@ impl Analyzer<'_> {
187187 ) ;
188188 }
189189 }
190+
191+ if function
192+ . effects
193+ . iter ( )
194+ . any ( |effect| matches ! ( effect, EffectDecl :: Name ( name) if name == "pure" ) )
195+ {
196+ for param in function
197+ . params
198+ . iter ( )
199+ . filter ( |param| param. effect == Some ( DataEffect :: Mut ) )
200+ {
201+ self . diagnostics . push (
202+ Diagnostic :: error (
203+ code:: INVALID_PURE_EFFECT ,
204+ format ! (
205+ "`{}` is declared pure but parameter `{}` is mutable." ,
206+ function. name, param. name
207+ ) ,
208+ param. span . clone ( ) ,
209+ "mutable parameter in pure function" ,
210+ )
211+ . with_cause ( "A `pure` function must not mutate reachable managed state." )
212+ . with_fix (
213+ "remove_pure_or_mut" ,
214+ "Remove `pure`, or change the parameter to `read` if the function does not mutate it." ,
215+ "manual" ,
216+ ) ,
217+ ) ;
218+ }
219+
220+ for effect in function
221+ . effects
222+ . iter ( )
223+ . filter ( |effect| matches ! ( effect, EffectDecl :: Retains ( _) ) )
224+ {
225+ self . diagnostics . push (
226+ Diagnostic :: error (
227+ code:: INVALID_PURE_EFFECT ,
228+ format ! (
229+ "`{}` is declared pure but also retains a parameter." ,
230+ function. name
231+ ) ,
232+ function. span . clone ( ) ,
233+ "retention in pure function" ,
234+ )
235+ . with_cause ( "A `pure` function must not retain parameters after returning." )
236+ . with_fix (
237+ "remove_pure_or_retains" ,
238+ format ! ( "Remove `pure` or remove `{}`." , effect_display( effect) ) ,
239+ "manual" ,
240+ ) ,
241+ ) ;
242+ }
243+ }
190244 }
191245 }
192246
@@ -553,6 +607,13 @@ fn effect_name(effect: &EffectDecl) -> &str {
553607 }
554608}
555609
610+ fn effect_display ( effect : & EffectDecl ) -> String {
611+ match effect {
612+ EffectDecl :: Name ( name) => name. clone ( ) ,
613+ EffectDecl :: Retains ( param) => format ! ( "retains({param})" ) ,
614+ }
615+ }
616+
556617fn duplicate_symbol_label ( kind : DuplicateSymbolKind ) -> & ' static str {
557618 match kind {
558619 DuplicateSymbolKind :: Function => "function" ,
0 commit comments