@@ -3171,7 +3171,7 @@ pub fn compile_to_llvm_ir(program: &Node) -> Result<String, String> {
31713171 let mut parameter_types = Vec :: new ( ) ;
31723172 let mut compile_params = Vec :: new ( ) ;
31733173 for ( param_name, param_type) in parameters {
3174- if ast:: unwrap_binding_const ( param_type) == & Type :: SkSelf {
3174+ if ast:: is_self_type ( param_type) {
31753175 continue ;
31763176 }
31773177 parameter_types. push ( llvm_type ( param_type, & structs, & enums) ?) ;
@@ -3685,7 +3685,7 @@ mod tests {
36853685 x: int;
36863686 y: int;
36873687
3688- function set_x(self, x: int): void {
3688+ function set_x(mut self, x: int): void {
36893689 self.x = x;
36903690 }
36913691
@@ -3706,6 +3706,89 @@ mod tests {
37063706 assert_eq ! ( stdout, "12\n " ) ;
37073707 }
37083708
3709+ #[ test]
3710+ fn runs_compiled_mut_self_method_program ( ) {
3711+ let stdout = compile_and_run (
3712+ r#"
3713+ struct Counter {
3714+ value: int;
3715+
3716+ function bump(mut self): void {
3717+ self.value = self.value + 1;
3718+ }
3719+
3720+ function get(self): int {
3721+ return self.value;
3722+ }
3723+ }
3724+
3725+ function main(): void {
3726+ counter: Counter = Counter { value: 9 };
3727+ counter.bump();
3728+ print(counter.get());
3729+ }
3730+ "# ,
3731+ )
3732+ . unwrap ( ) ;
3733+
3734+ assert_eq ! ( stdout, "10\n " ) ;
3735+ }
3736+
3737+ #[ test]
3738+ fn rejects_calling_mut_self_method_on_const_binding ( ) {
3739+ let result = compile_and_run (
3740+ r#"
3741+ struct Counter {
3742+ value: int;
3743+
3744+ function bump(mut self): void {
3745+ self.value = self.value + 1;
3746+ }
3747+ }
3748+
3749+ function main(): void {
3750+ const counter: Counter = Counter { value: 0 };
3751+ counter.bump();
3752+ }
3753+ "# ,
3754+ ) ;
3755+
3756+ assert ! ( result. is_err( ) ) ;
3757+ assert ! ( result
3758+ . unwrap_err( )
3759+ . contains( "cannot call mutating method through const or immutable receiver" ) ) ;
3760+ }
3761+
3762+ #[ test]
3763+ fn runs_compiled_const_pointer_readonly_method_program ( ) {
3764+ let stdout = compile_and_run (
3765+ r#"
3766+ struct Point {
3767+ x: int;
3768+
3769+ function get(self): int {
3770+ return self.x;
3771+ }
3772+ }
3773+
3774+ function print_point(point: *const Point): void {
3775+ print(point.get());
3776+ }
3777+
3778+ function main(): void {
3779+ heap: Allocator = System::allocator();
3780+ point: *Point = Point::create(heap);
3781+ point.x = 7;
3782+ print_point(point);
3783+ heap.destroy(point);
3784+ }
3785+ "# ,
3786+ )
3787+ . unwrap ( ) ;
3788+
3789+ assert_eq ! ( stdout, "7\n " ) ;
3790+ }
3791+
37093792 #[ test]
37103793 fn runs_compiled_slice_program ( ) {
37113794 let stdout = compile_and_run (
@@ -4260,22 +4343,22 @@ mod tests {
42604343 let stdout = compile_and_run (
42614344 r#"
42624345 trait Writer {
4263- function write(self, value: int): int;
4346+ function write(mut self, value: int): int;
42644347 }
42654348
42664349 trait Resettable {
4267- function reset(self): void;
4350+ function reset(mut self): void;
42684351 }
42694352
42704353 struct Counter {
42714354 value: int;
42724355
4273- function write(self, value: int): int {
4356+ function write(mut self, value: int): int {
42744357 self.value = self.value + value;
42754358 return self.value;
42764359 }
42774360
4278- function reset(self): void {
4361+ function reset(mut self): void {
42794362 self.value = 0;
42804363 }
42814364 }
@@ -4302,17 +4385,45 @@ mod tests {
43024385 }
43034386
43044387 #[ test]
4305- fn rejects_call_when_trait_bound_is_not_implemented ( ) {
4388+ fn rejects_trait_impl_with_receiver_mutability_mismatch ( ) {
43064389 let result = compile_and_run (
43074390 r#"
43084391 trait Writer {
4309- function write(self, value: int): int;
4392+ function write(mut self, value: int): int;
43104393 }
43114394
43124395 struct Counter {
43134396 value: int;
43144397
43154398 function write(self, value: int): int {
4399+ return self.value + value;
4400+ }
4401+ }
4402+
4403+ impl Writer for Counter {}
4404+
4405+ function main(): void {}
4406+ "# ,
4407+ ) ;
4408+
4409+ assert ! ( result. is_err( ) ) ;
4410+ assert ! ( result
4411+ . unwrap_err( )
4412+ . contains( "trait method `Writer.write` expects" ) ) ;
4413+ }
4414+
4415+ #[ test]
4416+ fn rejects_call_when_trait_bound_is_not_implemented ( ) {
4417+ let result = compile_and_run (
4418+ r#"
4419+ trait Writer {
4420+ function write(mut self, value: int): int;
4421+ }
4422+
4423+ struct Counter {
4424+ value: int;
4425+
4426+ function write(mut self, value: int): int {
43164427 self.value = self.value + value;
43174428 return self.value;
43184429 }
0 commit comments