diff --git a/compiler/erg_compiler/effectcheck.rs b/compiler/erg_compiler/effectcheck.rs index b21273f3..f7853912 100644 --- a/compiler/erg_compiler/effectcheck.rs +++ b/compiler/erg_compiler/effectcheck.rs @@ -374,6 +374,16 @@ impl SideEffectChecker { Expr::TypeAsc(type_asc) => { self.check_expr(&type_asc.expr); } + Expr::Accessor(acc) => { + if !self.in_context_effects_allowed() && acc.ref_t().is_mut_type() { + self.errs.push(EffectError::touch_mut_error( + self.cfg.input.clone(), + line!() as usize, + expr, + self.full_path(), + )); + } + } _ => {} } } diff --git a/compiler/erg_compiler/error.rs b/compiler/erg_compiler/error.rs index d6243817..471b6195 100644 --- a/compiler/erg_compiler/error.rs +++ b/compiler/erg_compiler/error.rs @@ -1383,6 +1383,25 @@ impl EffectError { caused_by, ) } + + pub fn touch_mut_error(input: Input, errno: usize, expr: &Expr, caused_by: String) -> Self { + Self::new( + ErrorCore::new( + vec![SubMessage::only_loc(expr.loc())], + switch_lang!( + "japanese" => "関数中で可変オブジェクトにアクセスすることは出来ません", + "simplified_chinese" => "函数中不能访问可变对象", + "traditional_chinese" => "函數中不能訪問可變對象", + "english" => "cannot access a mutable object in a function", + ), + errno, + HasEffect, + expr.loc(), + ), + input, + caused_by, + ) + } } pub type OwnershipError = TyCheckError; diff --git a/tests/should_ok/control_expr.er b/tests/should_ok/control_expr.er index 77fd2247..aab5a79a 100644 --- a/tests/should_ok/control_expr.er +++ b/tests/should_ok/control_expr.er @@ -23,3 +23,9 @@ print! counter w! do!(not(counter == 0)), do!: print! "counter = {counter}" counter.update!(i -> i - 1) + +counter2 = !2 +not_zero!() = not counter2 == 0 +while! not_zero!, do!: + print! "aaa" + counter2.update!(i -> i - 1)