diff --git a/crates/analyzer/src/db/queries/functions.rs b/crates/analyzer/src/db/queries/functions.rs index aa7280c2b3..7b911ea71c 100644 --- a/crates/analyzer/src/db/queries/functions.rs +++ b/crates/analyzer/src/db/queries/functions.rs @@ -90,12 +90,6 @@ pub fn function_signature( arg.span, "instances of `Context` must be named `ctx`", ); - } else if !function.parent(db).is_contract() { - scope.error( - "`ctx` cannot be passed into pure functions", - arg.span, - "`ctx` can only be passed into contract functions", - ); } else if self_decl.is_some() && index != 1 { scope.error( "invalid parameter order", diff --git a/crates/analyzer/src/namespace/types.rs b/crates/analyzer/src/namespace/types.rs index ad3113f595..3a0d60776a 100644 --- a/crates/analyzer/src/namespace/types.rs +++ b/crates/analyzer/src/namespace/types.rs @@ -418,31 +418,6 @@ impl FunctionSignature { pub fn expect_return_type(&self) -> FixedSize { self.return_type.clone().expect("fn return type error") } - - /// Parameters without `ctx`, if it is a contract function that declares it. - /// - /// This is used when calling a contract method externally. - pub fn external_params(&self) -> &[FunctionParam] { - if self.ctx_decl.is_some() { - &self.params[1..] - } else { - &self.params - } - } - - /// Parameter types without `ctx`, if it is a contract function that - /// declares it. - /// - /// This is used when calling a contract method externally. - /// - /// # Panics - /// Panics if any param type is an `Err` - pub fn external_param_types(&self) -> Vec { - self.external_params() - .iter() - .map(|param| param.typ.clone().expect("fn param type error")) - .collect() - } } impl Type { diff --git a/crates/analyzer/src/traversal/assignments.rs b/crates/analyzer/src/traversal/assignments.rs index 885d67f6a2..914402c724 100644 --- a/crates/analyzer/src/traversal/assignments.rs +++ b/crates/analyzer/src/traversal/assignments.rs @@ -18,42 +18,42 @@ pub fn assign(scope: &mut BlockScope, stmt: &Node) -> Result<(), F _ => unreachable!(), }; - let target_attributes = expressions::expr(scope, target, None)?; - let rhs_attributes = expressions::expr(scope, rhs, Some(&target_attributes.typ))?; + let target_attr = expressions::expr(scope, target, None)?; + let rhs_attr = expressions::expr(scope, rhs, Some(&target_attr.typ))?; check_assign_target(scope, target)?; - if target_attributes.typ != rhs_attributes.typ { + if target_attr.typ != rhs_attr.typ { scope.fancy_error( "mismatched types", vec![ - Label::primary( - target.span, - format!("this has type `{}`", target_attributes.typ), - ), + Label::primary(target.span, format!("this has type `{}`", target_attr.typ)), Label::secondary( rhs.span, - format!("this value has incompatible type `{}`", rhs_attributes.typ), + format!("this value has incompatible type `{}`", rhs_attr.typ), ), ], vec![], ); } - if target_attributes.mutable && !rhs_attributes.mutable { - // XXX - // scope.fancy_error( - // "sneaky mutation", // XXX better error - // vec![ - // Label::primary(target.span, "this is mutable"), - // Label::secondary(value.span, "this is immutable"), - // ], - // vec![], - // ); + if target_attr.mutable + && !rhs_attr.mutable + && !matches!(target_attr.location, Location::Storage { .. }) + && !matches!(rhs_attr.location, Location::Storage { .. }) + { + scope.fancy_error( + "sneaky mutation", // XXX better error + vec![ + Label::primary(target.span, "this is mutable"), + Label::secondary(rhs.span, "this is immutable"), + ], + vec![], + ); } if matches!( - (target_attributes.location, rhs_attributes.final_location(),), + (target_attr.location, rhs_attr.final_location(),), (Location::Memory, Location::Storage { .. }) ) { scope.fancy_error( @@ -151,18 +151,18 @@ pub fn aug_assign(scope: &mut BlockScope, stmt: &Node) -> Result<( _ => unreachable!(), }; - let target_attributes = expressions::expr(scope, target, None)?; - let rhs_attributes = expressions::expr(scope, rhs, Some(&target_attributes.typ))?; + let target_attr = expressions::expr(scope, target, None)?; + let rhs_attr = expressions::expr(scope, rhs, Some(&target_attr.typ))?; check_assign_target(scope, target)?; - if let Err(err) = operations::bin(&target_attributes.typ, &op.kind, &rhs_attributes.typ) { + if let Err(err) = operations::bin(&target_attr.typ, &op.kind, &rhs_attr.typ) { add_bin_operations_errors( scope, &op.kind, target.span, - &target_attributes.typ, + &target_attr.typ, rhs.span, - &rhs_attributes.typ, + &rhs_attr.typ, err, ); } diff --git a/crates/analyzer/src/traversal/call_args.rs b/crates/analyzer/src/traversal/call_args.rs index d4af67ef47..b7bca1d60c 100644 --- a/crates/analyzer/src/traversal/call_args.rs +++ b/crates/analyzer/src/traversal/call_args.rs @@ -11,6 +11,7 @@ use smol_str::SmolStr; pub trait LabeledParameter { fn label(&self) -> Option<&str>; fn typ(&self) -> Result; + fn mutable(&self) -> bool; } impl LabeledParameter for FunctionParam { @@ -20,6 +21,9 @@ impl LabeledParameter for FunctionParam { fn typ(&self) -> Result { self.typ.clone() } + fn mutable(&self) -> bool { + self.is_mut + } } impl LabeledParameter for EventField { @@ -29,15 +33,22 @@ impl LabeledParameter for EventField { fn typ(&self) -> Result { self.typ.clone() } + fn mutable(&self) -> bool { + self.name == "ctx" // hacktastic + } } -impl LabeledParameter for (SmolStr, Result) { +// XXX wtf is this +impl LabeledParameter for (SmolStr, Result, bool) { fn label(&self) -> Option<&str> { Some(&self.0) } fn typ(&self) -> Result { self.1.clone() } + fn mutable(&self) -> bool { + self.2 + } } pub fn validate_arg_count( @@ -99,55 +110,6 @@ pub fn validate_named_args( validate_arg_count(context, name, name_span, args, params.len(), "argument"); for (index, (param, arg)) in params.iter().zip(args.kind.iter()).enumerate() { - let expected_label = param.label(); - let arg_val = &arg.kind.value; - match (expected_label, &arg.kind.label) { - (Some(expected_label), Some(actual_label)) => { - if expected_label != actual_label.kind { - let notes = if params - .iter() - .any(|param| param.label() == Some(actual_label.kind.as_str())) - { - vec!["Note: arguments must be provided in order.".into()] - } else { - vec![] - }; - context.fancy_error( - "argument label mismatch", - vec![Label::primary( - actual_label.span, - format!("expected `{}`", expected_label), - )], - notes, - ); - } - } - (Some(expected_label), None) => match &arg_val.kind { - fe::Expr::Name(var_name) if var_name == expected_label => {} - _ => { - context.fancy_error( - "missing argument label", - vec![Label::primary( - Span::new(arg_val.span.file_id, arg_val.span.start, arg_val.span.start), - format!("add `{}:` here", expected_label), - )], - vec![format!( - "Note: this label is optional if the argument is a variable named `{}`.", - expected_label - )], - ); - } - }, - (None, Some(actual_label)) => { - context.error( - "argument should not be labeled", - actual_label.span, - "remove this label", - ); - } - (None, None) => {} - } - let param_type = param.typ()?; let val_attrs = assignable_expr(context, &arg.kind.value, Some(¶m_type.clone().into()))?; @@ -161,6 +123,69 @@ pub fn validate_named_args( ) }; context.type_error(&msg, arg.kind.value.span, ¶m_type, &val_attrs.typ); + } else { + let arg_val = &arg.kind.value; + + // We only emit label and mutability errors if the types match. + // If the types don't match, these errors can be confusing. + if param.mutable() && !val_attrs.mutable { + context.fancy_error( + "expected mut arg", // XXX better error + vec![ + Label::primary(arg_val.span, "this is not mutable"), + // Label::secondary(param.span, "mutates arg"), XXX parameter span + ], + vec![], + ); + } + + let expected_label = param.label(); + match (expected_label, &arg.kind.label) { + (Some(expected_label), Some(actual_label)) => { + if expected_label != actual_label.kind { + let notes = if params + .iter() + .any(|param| param.label() == Some(actual_label.kind.as_str())) + { + vec!["Note: arguments must be provided in order.".into()] + } else { + vec![] + }; + context.fancy_error( + "argument label mismatch", + vec![Label::primary( + actual_label.span, + format!("expected `{}`", expected_label), + )], + notes, + ); + } + } + (Some(expected_label), None) => match &arg_val.kind { + fe::Expr::Name(var_name) if var_name == expected_label => {} + _ => { + context.fancy_error( + "missing argument label", + vec![Label::primary( + Span::new(arg_val.span.file_id, arg_val.span.start, arg_val.span.start), + format!("add `{}:` here", expected_label), + )], + vec![format!( + "Note: this label is optional if the argument is a variable named `{}`.", + expected_label + )], + ); + } + }, + (None, Some(actual_label)) => { + context.error( + "argument should not be labeled", + actual_label.span, + "remove this label", + ); + } + (None, None) => {} + } } } Ok(()) diff --git a/crates/analyzer/src/traversal/expressions.rs b/crates/analyzer/src/traversal/expressions.rs index eddfc40e4d..8aa2baa1bf 100644 --- a/crates/analyzer/src/traversal/expressions.rs +++ b/crates/analyzer/src/traversal/expressions.rs @@ -1182,15 +1182,9 @@ fn expr_call_type_constructor( _ => {} } - if matches!(typ, Type::Contract(_)) { - validate_arg_count(context, &format!("{}", typ), name_span, args, 2, "argument"); - expect_no_label_on_arg(context, args, 0); - expect_no_label_on_arg(context, args, 1); - } else { - // These all expect 1 arg, for now. - validate_arg_count(context, &format!("{}", typ), name_span, args, 1, "argument"); - expect_no_label_on_arg(context, args, 0); - } + // These all expect 1 arg, for now. + validate_arg_count(context, &format!("{}", typ), name_span, args, 1, "argument"); + expect_no_label_on_arg(context, args, 0); let expr_attrs = match &typ { Type::String(string_type) => { @@ -1201,50 +1195,10 @@ fn expr_call_type_constructor( ExpressionAttributes::new(typ.clone(), Location::Memory, true) } Type::Contract(_) => { - if let Some(first_arg) = &args.kind.get(0) { - let first_arg_attr = assignable_expr(context, &first_arg.kind.value, None)?; - if let Some(context_type) = context.get_context_type() { - if first_arg_attr.typ != Type::Struct(context_type.clone()) { - context.type_error( - "type mismatch", - first_arg.span, - &context_type, - &first_arg_attr.typ, - ); - } - } else { - context.fancy_error( - "`Context` is not defined", - vec![ - Label::primary( - args.span, - "`ctx` must be defined and passed into the contract constructor", - ), - Label::secondary( - context.parent_function().name_span(context.db()), - "Note: declare `ctx` in this function signature", - ), - Label::secondary( - context.parent_function().name_span(context.db()), - "Example: `pub fn foo(ctx: Context, ...)`", - ), - ], - vec![ - "Note: import context with `use std::context::Context`".into(), - "Example: MyContract(ctx, contract_address)".into(), - ], - ); - } - } - if let Some(second_arg) = &args.kind.get(1) { - let second_arg_attr = assignable_expr(context, &second_arg.kind.value, None)?; - if second_arg_attr.typ != Type::Base(Base::Address) { - context.type_error( - "type mismatch", - second_arg.span, - &Base::Address, - &second_arg_attr.typ, - ); + if let Some(arg) = &args.kind.get(0) { + let arg_attr = assignable_expr(context, &arg.kind.value, None)?; + if arg_attr.typ != Type::Base(Base::Address) { + context.type_error("type mismatch", arg.span, &Base::Address, &arg_attr.typ); } } ExpressionAttributes::new(typ.clone(), Location::Value, true) @@ -1351,7 +1305,7 @@ fn expr_call_struct_constructor( .id .fields(db) .iter() - .map(|(name, field)| (name.clone(), field.typ(db))) + .map(|(name, field)| (name.clone(), field.typ(db), false)) .collect::>(); validate_named_args(context, name, name_span, args, &fields)?; @@ -1472,11 +1426,7 @@ fn expr_call_method( let sig = method.signature(context.db()); - let params = if is_self { - &sig.params - } else { - sig.external_params() - }; + let params = &sig.params; validate_named_args(context, &field.kind, field.span, args, params)?; let calltype = match class { diff --git a/crates/analyzer/tests/errors.rs b/crates/analyzer/tests/errors.rs index 133c77ef16..919cef53e6 100644 --- a/crates/analyzer/tests/errors.rs +++ b/crates/analyzer/tests/errors.rs @@ -339,15 +339,11 @@ test_ingot! { bad_visibility } test_file! { ctx_not_first } test_file! { ctx_not_after_self } test_file! { ctx_init } -test_file! { ctx_pure } test_file! { ctx_undeclared } test_file! { ctx_missing_internal_call } -test_file! { ctx_passed_external_call } test_file! { ctx_missing_create } -test_file! { ctx_missing_load } test_file! { ctx_missing_event } test_file! { ctx_builtins_param_incorrect_type } -test_file! { ctx_undefined_contract_init } test_file! { ctx_undefined_create } test_file! { ctx_undefined_create2 } test_file! { ctx_undefined_event } diff --git a/crates/analyzer/tests/snapshots/analysis__abi_encoding_stress.snap b/crates/analyzer/tests/snapshots/analysis__abi_encoding_stress.snap index abd5a42df4..00b2cd7433 100644 --- a/crates/analyzer/tests/snapshots/analysis__abi_encoding_stress.snap +++ b/crates/analyzer/tests/snapshots/analysis__abi_encoding_stress.snap @@ -765,14 +765,14 @@ note: note: ┌─ abi_encoding_stress.fe:76:5 │ -76 │ ╭ pub fn emit_my_event(self, ctx: Context): +76 │ ╭ pub fn emit_my_event(self, mut ctx: Context): 77 │ │ emit MyEvent( 78 │ │ ctx, 79 │ │ my_addrs: self.my_addrs.to_mem(), · │ 84 │ │ my_bytes: self.my_bytes.to_mem() 85 │ │ ) - │ ╰─────────^ attributes hash: 15495621399908028040 + │ ╰─────────^ attributes hash: 16861275983679698849 │ = FunctionSignature { self_decl: Some( @@ -786,7 +786,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( diff --git a/crates/analyzer/tests/snapshots/analysis__data_copying_stress.snap b/crates/analyzer/tests/snapshots/analysis__data_copying_stress.snap index b739fa39f8..328435303d 100644 --- a/crates/analyzer/tests/snapshots/analysis__data_copying_stress.snap +++ b/crates/analyzer/tests/snapshots/analysis__data_copying_stress.snap @@ -745,13 +745,13 @@ note: note: ┌─ data_copying_stress.fe:70:5 │ -70 │ ╭ pub fn emit_my_event(self, ctx: Context): +70 │ ╭ pub fn emit_my_event(self, mut ctx: Context): 71 │ │ emit_my_event_internal( 72 │ │ ctx, 73 │ │ self.my_string.to_mem(), 74 │ │ self.my_u256.to_mem() 75 │ │ ) - │ ╰─────────^ attributes hash: 3465640054853167022 + │ ╰─────────^ attributes hash: 11954428305323852639 │ = FunctionSignature { self_decl: Some( @@ -765,7 +765,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -832,9 +832,9 @@ note: note: ┌─ data_copying_stress.fe:77:5 │ -77 │ ╭ fn emit_my_event_internal(ctx: Context, _ my_string: String<42>, _ my_u256: u256): +77 │ ╭ fn emit_my_event_internal(mut ctx: Context, _ my_string: String<42>, _ my_u256: u256): 78 │ │ emit MyEvent(ctx, my_string, my_u256) - │ ╰─────────────────────────────────────────────^ attributes hash: 17322121531335310574 + │ ╰─────────────────────────────────────────────^ attributes hash: 7009973305464434950 │ = FunctionSignature { self_decl: None, @@ -843,7 +843,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -939,13 +939,13 @@ note: │ 80 │ ╭ pub fn set_my_addrs(mut self, my_addrs: Array): 81 │ │ self.my_addrs = my_addrs - │ ╰────────────────────────────────^ attributes hash: 6596479074654462354 + │ ╰────────────────────────────────^ attributes hash: 523075029312973845 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 2269..2273, + span: 2277..2281, }, ), ctx_decl: None, @@ -990,13 +990,13 @@ note: │ 83 │ ╭ pub fn get_my_second_addr(self) -> address: 84 │ │ return self.my_addrs[1] - │ ╰───────────────────────────────^ attributes hash: 11296848741241405402 + │ ╰───────────────────────────────^ attributes hash: 12871993013748740095 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 2369..2373, + span: 2377..2381, }, ), ctx_decl: None, diff --git a/crates/analyzer/tests/snapshots/analysis__erc20_token.snap b/crates/analyzer/tests/snapshots/analysis__erc20_token.snap index 100c71c6df..5787865beb 100644 --- a/crates/analyzer/tests/snapshots/analysis__erc20_token.snap +++ b/crates/analyzer/tests/snapshots/analysis__erc20_token.snap @@ -44,13 +44,13 @@ note: │ 27 │ ╭ pub fn name(self) -> String<100>: 28 │ │ return self._name.to_mem() - │ ╰──────────────────────────────────^ attributes hash: 10326840621732793325 + │ ╰──────────────────────────────────^ attributes hash: 15291032982106959294 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 681..685, + span: 685..689, }, ), ctx_decl: None, @@ -87,13 +87,13 @@ note: │ 30 │ ╭ pub fn symbol(self) -> String<100>: 31 │ │ return self._symbol.to_mem() - │ ╰────────────────────────────────────^ attributes hash: 2821531269978251174 + │ ╰────────────────────────────────────^ attributes hash: 11757271242284753762 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 757..761, + span: 761..765, }, ), ctx_decl: None, @@ -130,13 +130,13 @@ note: │ 33 │ ╭ pub fn decimals(self) -> u8: 34 │ │ return self._decimals - │ ╰─────────────────────────────^ attributes hash: 15860653689999316634 + │ ╰─────────────────────────────^ attributes hash: 8983671994389645110 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 837..841, + span: 841..845, }, ), ctx_decl: None, @@ -167,13 +167,13 @@ note: │ 36 │ ╭ pub fn totalSupply(self) -> u256: 37 │ │ return self._total_supply - │ ╰─────────────────────────────────^ attributes hash: 6752201590413781727 + │ ╰─────────────────────────────────^ attributes hash: 15442337897824434251 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 904..908, + span: 908..912, }, ), ctx_decl: None, @@ -204,13 +204,13 @@ note: │ 39 │ ╭ pub fn balanceOf(self, _ account: address) -> u256: 40 │ │ return self._balances[account] - │ ╰──────────────────────────────────────^ attributes hash: 7037225850851392916 + │ ╰──────────────────────────────────────^ attributes hash: 3457882247067336686 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 975..979, + span: 979..983, }, ), ctx_decl: None, @@ -260,16 +260,16 @@ note: note: ┌─ erc20_token.fe:42:5 │ -42 │ ╭ pub fn transfer(mut self, ctx: Context, recipient: address, value: u256) -> bool: +42 │ ╭ pub fn transfer(mut self, mut ctx: Context, recipient: address, value: u256) -> bool: 43 │ │ self._transfer(ctx, sender: ctx.msg_sender(), recipient, value) 44 │ │ return true - │ ╰───────────────────^ attributes hash: 17848380029420472885 + │ ╰───────────────────^ attributes hash: 11720873512389391843 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 1074..1078, + span: 1078..1082, }, ), ctx_decl: Some( @@ -277,7 +277,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -350,13 +350,13 @@ note: │ 46 │ ╭ pub fn allowance(self, owner: address, spender: address) -> u256: 47 │ │ return self._allowances[owner][spender] - │ ╰───────────────────────────────────────────────^ attributes hash: 5571416063430298361 + │ ╰───────────────────────────────────────────────^ attributes hash: 8052648076460775305 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 1250..1254, + span: 1258..1262, }, ), ctx_decl: None, @@ -422,16 +422,16 @@ note: note: ┌─ erc20_token.fe:49:5 │ -49 │ ╭ pub fn approve(mut self, ctx: Context, spender: address, value: u256) -> bool: +49 │ ╭ pub fn approve(mut self, mut ctx: Context, spender: address, value: u256) -> bool: 50 │ │ self._approve(ctx, owner: ctx.msg_sender(), spender, value) 51 │ │ return true - │ ╰───────────────────^ attributes hash: 1010517131892538097 + │ ╰───────────────────^ attributes hash: 4167606951714633258 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 1371..1375, + span: 1379..1383, }, ), ctx_decl: Some( @@ -439,7 +439,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -510,18 +510,18 @@ note: note: ┌─ erc20_token.fe:53:5 │ -53 │ ╭ pub fn transferFrom(mut self, ctx: Context, sender: address, recipient: address, value: u256) -> bool: +53 │ ╭ pub fn transferFrom(mut self, mut ctx: Context, sender: address, recipient: address, value: u256) -> bool: 54 │ │ assert self._allowances[sender][ctx.msg_sender()] >= value 55 │ │ self._transfer(ctx, sender, recipient, value) 56 │ │ self._approve(ctx, owner: sender, spender: ctx.msg_sender(), value: self._allowances[sender][ctx.msg_sender()] - value) 57 │ │ return true - │ ╰───────────────────^ attributes hash: 7939067401153478982 + │ ╰───────────────────^ attributes hash: 2011147251377795828 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 1548..1552, + span: 1560..1564, }, ), ctx_decl: Some( @@ -529,7 +529,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -697,16 +697,16 @@ note: note: ┌─ erc20_token.fe:59:5 │ -59 │ ╭ pub fn increaseAllowance(mut self, ctx: Context, spender: address, addedValue: u256) -> bool: +59 │ ╭ pub fn increaseAllowance(mut self, mut ctx: Context, spender: address, addedValue: u256) -> bool: 60 │ │ self._approve(ctx, owner: ctx.msg_sender(), spender, value: self._allowances[ctx.msg_sender()][spender] + addedValue) 61 │ │ return true - │ ╰───────────────────^ attributes hash: 18429228409985716741 + │ ╰───────────────────^ attributes hash: 9008741857569437628 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 1930..1934, + span: 1946..1950, }, ), ctx_decl: Some( @@ -714,7 +714,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -821,16 +821,16 @@ note: note: ┌─ erc20_token.fe:63:5 │ -63 │ ╭ pub fn decreaseAllowance(mut self, ctx: Context, spender: address, subtractedValue: u256) -> bool: +63 │ ╭ pub fn decreaseAllowance(mut self, mut ctx: Context, spender: address, subtractedValue: u256) -> bool: 64 │ │ self._approve(ctx, owner: ctx.msg_sender(), spender, value: self._allowances[ctx.msg_sender()][spender] - subtractedValue) 65 │ │ return true - │ ╰───────────────────^ attributes hash: 6163388348340102461 + │ ╰───────────────────^ attributes hash: 15620430256914061132 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 2175..2179, + span: 2195..2199, }, ), ctx_decl: Some( @@ -838,7 +838,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -945,20 +945,20 @@ note: note: ┌─ erc20_token.fe:67:5 │ -67 │ ╭ fn _transfer(mut self, ctx: Context, sender: address, recipient: address, value: u256): +67 │ ╭ fn _transfer(mut self, mut ctx: Context, sender: address, recipient: address, value: u256): 68 │ │ assert sender != address(0) 69 │ │ assert recipient != address(0) 70 │ │ _before_token_transfer(from: sender, to: recipient, value) 71 │ │ self._balances[sender] = self._balances[sender] - value 72 │ │ self._balances[recipient] = self._balances[recipient] + value 73 │ │ emit Transfer(ctx, from: sender, to: recipient, value) - │ ╰──────────────────────────────────────────────────────────────^ attributes hash: 10498598608658691613 + │ ╰──────────────────────────────────────────────────────────────^ attributes hash: 14929845535764503237 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 2418..2422, + span: 2442..2446, }, ), ctx_decl: Some( @@ -966,7 +966,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -1195,19 +1195,19 @@ note: note: ┌─ erc20_token.fe:75:5 │ -75 │ ╭ fn _mint(mut self, ctx: Context, account: address, value: u256): +75 │ ╭ fn _mint(mut self, mut ctx: Context, account: address, value: u256): 76 │ │ assert account != address(0) 77 │ │ _before_token_transfer(from: address(0), to: account, value) 78 │ │ self._total_supply = self._total_supply + value 79 │ │ self._balances[account] = self._balances[account] + value 80 │ │ emit Transfer(ctx, from: address(0), to: account, value) - │ ╰────────────────────────────────────────────────────────────────^ attributes hash: 14466326291355393221 + │ ╰────────────────────────────────────────────────────────────────^ attributes hash: 7838554142405633761 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 2846..2850, + span: 2874..2878, }, ), ctx_decl: Some( @@ -1215,7 +1215,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -1415,19 +1415,19 @@ note: note: ┌─ erc20_token.fe:82:5 │ -82 │ ╭ fn _burn(mut self, ctx: Context, account: address, value: u256): +82 │ ╭ fn _burn(mut self, mut ctx: Context, account: address, value: u256): 83 │ │ assert account != address(0) 84 │ │ _before_token_transfer(from: account, to: address(0), value) 85 │ │ self._balances[account] = self._balances[account] - value 86 │ │ self._total_supply = self._total_supply - value 87 │ │ emit Transfer(ctx, from: account, to: address(0), value) - │ ╰────────────────────────────────────────────────────────────────^ attributes hash: 4943182168588040219 + │ ╰────────────────────────────────────────────────────────────────^ attributes hash: 1807078948769823859 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 3209..3213, + span: 3241..3245, }, ), ctx_decl: Some( @@ -1435,7 +1435,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -1636,18 +1636,18 @@ note: note: ┌─ erc20_token.fe:89:5 │ -89 │ ╭ fn _approve(mut self, ctx: Context, owner: address, spender: address, value: u256): +89 │ ╭ fn _approve(mut self, mut ctx: Context, owner: address, spender: address, value: u256): 90 │ │ assert owner != address(0) 91 │ │ assert spender != address(0) 92 │ │ self._allowances[owner][spender] = value 93 │ │ emit Approval(ctx, owner, spender, value) - │ ╰─────────────────────────────────────────────────^ attributes hash: 11548731968227902483 + │ ╰─────────────────────────────────────────────────^ attributes hash: 12261238233058268738 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 3575..3579, + span: 3611..3615, }, ), ctx_decl: Some( @@ -1655,7 +1655,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -1821,13 +1821,13 @@ note: │ 95 │ ╭ fn _setup_decimals(mut self, _ decimals_: u8): 96 │ │ self._decimals = decimals_ - │ ╰──────────────────────────────────^ attributes hash: 7541839769003135213 + │ ╰──────────────────────────────────^ attributes hash: 9816645932550073125 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 3842..3846, + span: 3882..3886, }, ), ctx_decl: None, diff --git a/crates/analyzer/tests/snapshots/analysis__events.snap b/crates/analyzer/tests/snapshots/analysis__events.snap index 44f89bfb1b..b7c3475f80 100644 --- a/crates/analyzer/tests/snapshots/analysis__events.snap +++ b/crates/analyzer/tests/snapshots/analysis__events.snap @@ -40,9 +40,9 @@ note: note: ┌─ events.fe:21:5 │ -21 │ ╭ pub fn emit_nums(ctx: Context): +21 │ ╭ pub fn emit_nums(mut ctx: Context): 22 │ │ emit Nums(ctx, num1: 26, num2: 42) - │ ╰──────────────────────────────────────────^ attributes hash: 1359797249093753473 + │ ╰──────────────────────────────────────────^ attributes hash: 3107376239596606736 │ = FunctionSignature { self_decl: None, @@ -51,7 +51,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -117,9 +117,9 @@ note: note: ┌─ events.fe:24:5 │ -24 │ ╭ pub fn emit_bases(ctx: Context, addr: address): +24 │ ╭ pub fn emit_bases(mut ctx: Context, addr: address): 25 │ │ emit Bases(ctx, num: 26, addr) - │ ╰──────────────────────────────────────^ attributes hash: 16896664860110700062 + │ ╰──────────────────────────────────────^ attributes hash: 10645192025445674186 │ = FunctionSignature { self_decl: None, @@ -128,7 +128,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -202,9 +202,9 @@ note: note: ┌─ events.fe:27:5 │ -27 │ ╭ pub fn emit_mix(ctx: Context, addr: address, my_bytes: Array): +27 │ ╭ pub fn emit_mix(mut ctx: Context, addr: address, my_bytes: Array): 28 │ │ emit Mix(ctx, num1: 26, addr, num2: 42, my_bytes) - │ ╰─────────────────────────────────────────────────────────^ attributes hash: 6486390919707987295 + │ ╰─────────────────────────────────────────────────────────^ attributes hash: 14298327822992287135 │ = FunctionSignature { self_decl: None, @@ -213,7 +213,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -329,12 +329,12 @@ note: note: ┌─ events.fe:30:5 │ -30 │ ╭ pub fn emit_addresses(ctx: Context, addr1: address, addr2: address): +30 │ ╭ pub fn emit_addresses(mut ctx: Context, addr1: address, addr2: address): 31 │ │ let mut addrs: Array 32 │ │ addrs[0] = addr1 33 │ │ addrs[1] = addr2 34 │ │ emit Addresses(ctx, addrs) - │ ╰──────────────────────────────────^ attributes hash: 11469142727854969771 + │ ╰──────────────────────────────────^ attributes hash: 12718344820069656177 │ = FunctionSignature { self_decl: None, @@ -343,7 +343,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( diff --git a/crates/analyzer/tests/snapshots/analysis__external_contract.snap b/crates/analyzer/tests/snapshots/analysis__external_contract.snap index f526f1e5f3..75fb3cd7dd 100644 --- a/crates/analyzer/tests/snapshots/analysis__external_contract.snap +++ b/crates/analyzer/tests/snapshots/analysis__external_contract.snap @@ -4,41 +4,176 @@ expression: "build_snapshot(&db, module)" --- note: - ┌─ external_contract.fe:5:9 + ┌─ external_contract.fe:4:5 │ -5 │ my_num: u256 - │ ^^^^^^^^^^^^ u256 -6 │ my_addrs: Array - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Array -7 │ my_string: String<11> - │ ^^^^^^^^^^^^^^^^^^^^^ String<11> +4 │ num: u256 + │ ^^^^^^^^^ u256 +5 │ addrs: Array + │ ^^^^^^^^^^^^^^^^^^^^^^^^ Array +6 │ str: String<11> + │ ^^^^^^^^^^^^^^^ String<11> note: - ┌─ external_contract.fe:9:5 + ┌─ external_contract.fe:8:1 + │ +8 │ ╭ fn emit_MyEvent(mut ctx: Context, _ num: u256, _ addrs: Array, _ str: String<11>): +9 │ │ emit MyEvent(ctx, num, addrs, str) + │ ╰────────────────────────────────────^ attributes hash: 16260166060737977544 + │ + = FunctionSignature { + self_decl: None, + ctx_decl: Some( + Mutable, + ), + params: [ + FunctionParam { + is_mut: true, + label: None, + name: "ctx", + typ: Ok( + Struct( + Struct { + name: "Context", + field_count: 0, + }, + ), + ), + }, + FunctionParam { + is_mut: false, + label: Some( + "_", + ), + name: "num", + typ: Ok( + Base( + Numeric( + U256, + ), + ), + ), + }, + FunctionParam { + is_mut: false, + label: Some( + "_", + ), + name: "addrs", + typ: Ok( + Array( + Array { + size: 5, + inner: Address, + }, + ), + ), + }, + FunctionParam { + is_mut: false, + label: Some( + "_", + ), + name: "str", + typ: Ok( + String( + FeString { + max_size: 11, + }, + ), + ), + }, + ], + return_type: Ok( + Base( + Unit, + ), + ), + } + +note: + ┌─ external_contract.fe:9:16 + │ +9 │ emit MyEvent(ctx, num, addrs, str) + │ ^^^ ^^^ ^^^^^ ^^^ String<11>: Memory + │ │ │ │ + │ │ │ Array: Memory + │ │ u256: Value + │ Context: Memory + +note: + ┌─ external_contract.fe:9:3 + │ +9 │ emit MyEvent(ctx, num, addrs, str) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attributes hash: 13196953629212675036 + │ + = Event { + name: "MyEvent", + fields: [ + EventField { + name: "num", + typ: Ok( + Base( + Numeric( + U256, + ), + ), + ), + is_indexed: false, + }, + EventField { + name: "addrs", + typ: Ok( + Array( + Array { + size: 5, + inner: Address, + }, + ), + ), + is_indexed: false, + }, + EventField { + name: "str", + typ: Ok( + String( + FeString { + max_size: 11, + }, + ), + ), + is_indexed: false, + }, + ], + } + +note: + ┌─ external_contract.fe:13:5 + │ +13 │ my_num: u256 + │ ^^^^^^^^^^^^ u256 +14 │ my_addrs: Array + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Array +15 │ my_string: String<11> + │ ^^^^^^^^^^^^^^^^^^^^^ String<11> + +note: + ┌─ external_contract.fe:17:5 │ - 9 │ ╭ pub fn emit_event(ctx: Context, my_num: u256, my_addrs: Array, my_string: String<11>): -10 │ │ emit MyEvent(ctx, my_num, my_addrs, my_string) - │ ╰──────────────────────────────────────────────────────^ attributes hash: 16963582623619520336 +17 │ ╭ pub fn set_stuff(mut self, my_num: u256, my_addrs: Array, my_string: String<11>): +18 │ │ self.my_num = my_num +19 │ │ self.my_addrs = my_addrs +20 │ │ self.my_string = my_string + │ ╰──────────────────────────────────^ attributes hash: 1162131942469260415 │ = FunctionSignature { - self_decl: None, - ctx_decl: Some( - Mutable, + self_decl: Some( + SelfDecl { + kind: MutRef, + span: 355..359, + }, ), + ctx_decl: None, params: [ - FunctionParam { - is_mut: false, - label: None, - name: "ctx", - typ: Ok( - Struct( - Struct { - name: "Context", - field_count: 0, - }, - ), - ), - }, FunctionParam { is_mut: false, label: None, @@ -85,70 +220,135 @@ note: } note: - ┌─ external_contract.fe:10:22 + ┌─ external_contract.fe:18:9 │ -10 │ emit MyEvent(ctx, my_num, my_addrs, my_string) - │ ^^^ ^^^^^^ ^^^^^^^^ ^^^^^^^^^ String<11>: Memory - │ │ │ │ - │ │ │ Array: Memory - │ │ u256: Value - │ Context: Memory +18 │ self.my_num = my_num + │ ^^^^ Foo: Value note: - ┌─ external_contract.fe:10:9 + ┌─ external_contract.fe:18:9 │ -10 │ emit MyEvent(ctx, my_num, my_addrs, my_string) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attributes hash: 3872046667435269452 +18 │ self.my_num = my_num + │ ^^^^^^^^^^^ ^^^^^^ u256: Value + │ │ + │ u256: Storage { nonce: Some(0) } +19 │ self.my_addrs = my_addrs + │ ^^^^ Foo: Value + +note: + ┌─ external_contract.fe:19:9 │ - = Event { - name: "MyEvent", - fields: [ - EventField { - name: "my_num", - typ: Ok( - Base( - Numeric( - U256, - ), - ), - ), - is_indexed: false, - }, - EventField { - name: "my_addrs", - typ: Ok( - Array( - Array { - size: 5, - inner: Address, - }, - ), - ), - is_indexed: false, +19 │ self.my_addrs = my_addrs + │ ^^^^^^^^^^^^^ ^^^^^^^^ Array: Memory + │ │ + │ Array: Storage { nonce: Some(1) } +20 │ self.my_string = my_string + │ ^^^^ Foo: Value + +note: + ┌─ external_contract.fe:20:9 + │ +20 │ self.my_string = my_string + │ ^^^^^^^^^^^^^^ ^^^^^^^^^ String<11>: Memory + │ │ + │ String<11>: Storage { nonce: Some(2) } + +note: + ┌─ external_contract.fe:22:5 + │ +22 │ ╭ pub fn emit_event(self, mut ctx: Context): +23 │ │ emit_MyEvent(ctx, self.my_num, self.my_addrs.to_mem(), self.my_string.to_mem()) + │ ╰───────────────────────────────────────────────────────────────────────────────────────^ attributes hash: 2307278666021129213 + │ + = FunctionSignature { + self_decl: Some( + SelfDecl { + kind: Ref, + span: 548..552, }, - EventField { - name: "my_string", + ), + ctx_decl: Some( + Mutable, + ), + params: [ + FunctionParam { + is_mut: true, + label: None, + name: "ctx", typ: Ok( - String( - FeString { - max_size: 11, + Struct( + Struct { + name: "Context", + field_count: 0, }, ), ), - is_indexed: false, }, ], + return_type: Ok( + Base( + Unit, + ), + ), } note: - ┌─ external_contract.fe:12:5 + ┌─ external_contract.fe:23:22 + │ +23 │ emit_MyEvent(ctx, self.my_num, self.my_addrs.to_mem(), self.my_string.to_mem()) + │ ^^^ ^^^^ Foo: Value + │ │ + │ Context: Memory + +note: + ┌─ external_contract.fe:23:27 + │ +23 │ emit_MyEvent(ctx, self.my_num, self.my_addrs.to_mem(), self.my_string.to_mem()) + │ ^^^^^^^^^^^ ^^^^ Foo: Value + │ │ + │ u256: Storage { nonce: Some(0) } => Value + +note: + ┌─ external_contract.fe:23:40 + │ +23 │ emit_MyEvent(ctx, self.my_num, self.my_addrs.to_mem(), self.my_string.to_mem()) + │ ^^^^^^^^^^^^^ Array: Storage { nonce: Some(1) } + +note: + ┌─ external_contract.fe:23:40 + │ +23 │ emit_MyEvent(ctx, self.my_num, self.my_addrs.to_mem(), self.my_string.to_mem()) + │ ^^^^^^^^^^^^^^^^^^^^^^ ^^^^ Foo: Value + │ │ + │ Array: Storage { nonce: Some(1) } => Memory + +note: + ┌─ external_contract.fe:23:64 + │ +23 │ emit_MyEvent(ctx, self.my_num, self.my_addrs.to_mem(), self.my_string.to_mem()) + │ ^^^^^^^^^^^^^^ String<11>: Storage { nonce: Some(2) } + +note: + ┌─ external_contract.fe:23:64 + │ +23 │ emit_MyEvent(ctx, self.my_num, self.my_addrs.to_mem(), self.my_string.to_mem()) + │ ^^^^^^^^^^^^^^^^^^^^^^^ String<11>: Storage { nonce: Some(2) } => Memory + +note: + ┌─ external_contract.fe:23:9 + │ +23 │ emit_MyEvent(ctx, self.my_num, self.my_addrs.to_mem(), self.my_string.to_mem()) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (): Value + +note: + ┌─ external_contract.fe:25:5 │ -12 │ ╭ pub fn build_array(a: u256, b: u256) -> Array: -13 │ │ let mut my_array: Array -14 │ │ my_array[0] = a -15 │ │ my_array[1] = a * b -16 │ │ my_array[2] = b -17 │ │ return my_array +25 │ ╭ pub fn build_array(a: u256, b: u256) -> Array: +26 │ │ let mut my_array: Array +27 │ │ my_array[0] = a +28 │ │ my_array[1] = a * b +29 │ │ my_array[2] = b +30 │ │ return my_array │ ╰───────────────────────^ attributes hash: 10662183460702627724 │ = FunctionSignature { @@ -193,71 +393,71 @@ note: } note: - ┌─ external_contract.fe:13:27 + ┌─ external_contract.fe:26:27 │ -13 │ let mut my_array: Array +26 │ let mut my_array: Array │ ^^^^^^^^^^^^^^ Array note: - ┌─ external_contract.fe:14:9 + ┌─ external_contract.fe:27:9 │ -14 │ my_array[0] = a +27 │ my_array[0] = a │ ^^^^^^^^ ^ u256: Value │ │ │ Array: Memory note: - ┌─ external_contract.fe:14:9 + ┌─ external_contract.fe:27:9 │ -14 │ my_array[0] = a +27 │ my_array[0] = a │ ^^^^^^^^^^^ ^ u256: Value │ │ │ u256: Memory -15 │ my_array[1] = a * b +28 │ my_array[1] = a * b │ ^^^^^^^^ ^ u256: Value │ │ │ Array: Memory note: - ┌─ external_contract.fe:15:9 + ┌─ external_contract.fe:28:9 │ -15 │ my_array[1] = a * b +28 │ my_array[1] = a * b │ ^^^^^^^^^^^ ^ ^ u256: Value │ │ │ │ │ u256: Value │ u256: Memory note: - ┌─ external_contract.fe:15:23 + ┌─ external_contract.fe:28:23 │ -15 │ my_array[1] = a * b +28 │ my_array[1] = a * b │ ^^^^^ u256: Value -16 │ my_array[2] = b +29 │ my_array[2] = b │ ^^^^^^^^ ^ u256: Value │ │ │ Array: Memory note: - ┌─ external_contract.fe:16:9 + ┌─ external_contract.fe:29:9 │ -16 │ my_array[2] = b +29 │ my_array[2] = b │ ^^^^^^^^^^^ ^ u256: Value │ │ │ u256: Memory -17 │ return my_array +30 │ return my_array │ ^^^^^^^^ Array: Memory note: - ┌─ external_contract.fe:20:5 + ┌─ external_contract.fe:33:5 │ -20 │ ╭ pub fn call_emit_event( -21 │ │ ctx: Context, -22 │ │ foo_address: address, -23 │ │ my_num: u256, +33 │ ╭ pub fn call_emit_event( +34 │ │ mut ctx: Context, +35 │ │ foo_address: address, +36 │ │ my_num: u256, · │ -27 │ │ let foo: Foo = Foo(ctx, foo_address) -28 │ │ foo.emit_event(my_num, my_addrs, my_string) - │ ╰───────────────────────────────────────────────────^ attributes hash: 317901856936457740 +41 │ │ foo.set_stuff(my_num, my_addrs, my_string) +42 │ │ foo.emit_event(ctx) + │ ╰───────────────────────────^ attributes hash: 4061500227430759613 │ = FunctionSignature { self_decl: None, @@ -266,7 +466,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -334,48 +534,56 @@ note: } note: - ┌─ external_contract.fe:27:18 + ┌─ external_contract.fe:40:18 │ -27 │ let foo: Foo = Foo(ctx, foo_address) +40 │ let foo: Foo = Foo(foo_address) │ ^^^ Foo note: - ┌─ external_contract.fe:27:28 + ┌─ external_contract.fe:40:28 │ -27 │ let foo: Foo = Foo(ctx, foo_address) - │ ^^^ ^^^^^^^^^^^ address: Value - │ │ - │ Context: Memory +40 │ let foo: Foo = Foo(foo_address) + │ ^^^^^^^^^^^ address: Value note: - ┌─ external_contract.fe:27:24 + ┌─ external_contract.fe:40:24 │ -27 │ let foo: Foo = Foo(ctx, foo_address) - │ ^^^^^^^^^^^^^^^^^^^^^ Foo: Value -28 │ foo.emit_event(my_num, my_addrs, my_string) - │ ^^^ ^^^^^^ ^^^^^^^^ ^^^^^^^^^ String<11>: Memory - │ │ │ │ - │ │ │ Array: Memory - │ │ u256: Value +40 │ let foo: Foo = Foo(foo_address) + │ ^^^^^^^^^^^^^^^^ Foo: Value +41 │ foo.set_stuff(my_num, my_addrs, my_string) + │ ^^^ ^^^^^^ ^^^^^^^^ ^^^^^^^^^ String<11>: Memory + │ │ │ │ + │ │ │ Array: Memory + │ │ u256: Value │ Foo: Value note: - ┌─ external_contract.fe:28:9 + ┌─ external_contract.fe:41:9 │ -28 │ foo.emit_event(my_num, my_addrs, my_string) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (): Value +41 │ foo.set_stuff(my_num, my_addrs, my_string) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (): Value +42 │ foo.emit_event(ctx) + │ ^^^ ^^^ Context: Memory + │ │ + │ Foo: Value note: - ┌─ external_contract.fe:30:5 + ┌─ external_contract.fe:42:9 + │ +42 │ foo.emit_event(ctx) + │ ^^^^^^^^^^^^^^^^^^^ (): Value + +note: + ┌─ external_contract.fe:44:5 │ -30 │ ╭ pub fn call_build_array( -31 │ │ ctx: Context, -32 │ │ foo_address: address, -33 │ │ a: u256, +44 │ ╭ pub fn call_build_array( +45 │ │ mut ctx: Context, +46 │ │ foo_address: address, +47 │ │ a: u256, · │ -36 │ │ let foo: Foo = Foo(ctx, foo_address) -37 │ │ return foo.build_array(a, b) - │ ╰────────────────────────────────────^ attributes hash: 17875366176760989694 +50 │ │ let foo: Foo = Foo(foo_address) +51 │ │ return foo.build_array(a, b) + │ ╰────────────────────────────────────^ attributes hash: 613046287810446946 │ = FunctionSignature { self_decl: None, @@ -384,7 +592,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -444,34 +652,32 @@ note: } note: - ┌─ external_contract.fe:36:18 + ┌─ external_contract.fe:50:18 │ -36 │ let foo: Foo = Foo(ctx, foo_address) +50 │ let foo: Foo = Foo(foo_address) │ ^^^ Foo note: - ┌─ external_contract.fe:36:28 + ┌─ external_contract.fe:50:28 │ -36 │ let foo: Foo = Foo(ctx, foo_address) - │ ^^^ ^^^^^^^^^^^ address: Value - │ │ - │ Context: Memory +50 │ let foo: Foo = Foo(foo_address) + │ ^^^^^^^^^^^ address: Value note: - ┌─ external_contract.fe:36:24 + ┌─ external_contract.fe:50:24 │ -36 │ let foo: Foo = Foo(ctx, foo_address) - │ ^^^^^^^^^^^^^^^^^^^^^ Foo: Value -37 │ return foo.build_array(a, b) +50 │ let foo: Foo = Foo(foo_address) + │ ^^^^^^^^^^^^^^^^ Foo: Value +51 │ return foo.build_array(a, b) │ ^^^ ^ ^ u256: Value │ │ │ │ │ u256: Value │ Foo: Value note: - ┌─ external_contract.fe:37:16 + ┌─ external_contract.fe:51:16 │ -37 │ return foo.build_array(a, b) +51 │ return foo.build_array(a, b) │ ^^^^^^^^^^^^^^^^^^^^^ Array: Memory diff --git a/crates/analyzer/tests/snapshots/analysis__guest_book.snap b/crates/analyzer/tests/snapshots/analysis__guest_book.snap index d641c6ff36..dc2f32319f 100644 --- a/crates/analyzer/tests/snapshots/analysis__guest_book.snap +++ b/crates/analyzer/tests/snapshots/analysis__guest_book.snap @@ -18,13 +18,13 @@ note: note: ┌─ guest_book.fe:13:5 │ -13 │ ╭ pub fn sign(mut self, ctx: Context, book_msg: String<100>): +13 │ ╭ pub fn sign(mut self, mut ctx: Context, book_msg: String<100>): 14 │ │ # All storage access is explicit using `self.` 15 │ │ self.messages[ctx.msg_sender()] = book_msg 16 │ │ 17 │ │ # Emit the `Signed` event 18 │ │ emit Signed(ctx, book_msg) - │ ╰──────────────────────────────────^ attributes hash: 10126475880915437347 + │ ╰──────────────────────────────────^ attributes hash: 2554340159850801868 │ = FunctionSignature { self_decl: Some( @@ -38,7 +38,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -133,13 +133,13 @@ note: 21 │ │ # Copying data from storage to memory 22 │ │ # has to be done explicitly via `to_mem()` 23 │ │ return self.messages[addr].to_mem() - │ ╰───────────────────────────────────────────^ attributes hash: 8213707984659401459 + │ ╰───────────────────────────────────────────^ attributes hash: 3374615757926604854 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 603..607, + span: 607..611, }, ), ctx_decl: None, diff --git a/crates/analyzer/tests/snapshots/analysis__module_level_events.snap b/crates/analyzer/tests/snapshots/analysis__module_level_events.snap index 9372799d7d..6d7de78d7e 100644 --- a/crates/analyzer/tests/snapshots/analysis__module_level_events.snap +++ b/crates/analyzer/tests/snapshots/analysis__module_level_events.snap @@ -16,9 +16,9 @@ note: note: ┌─ module_level_events.fe:9:5 │ - 9 │ ╭ fn transfer(ctx: Context, to : address, value : u256): + 9 │ ╭ fn transfer(mut ctx: Context, to: address, value: u256): 10 │ │ emit Transfer(ctx, sender: ctx.msg_sender(), receiver: to, value) - │ ╰─────────────────────────────────────────────────────────────────────────^ attributes hash: 15823579903600345363 + │ ╰─────────────────────────────────────────────────────────────────────────^ attributes hash: 4681643600085308816 │ = FunctionSignature { self_decl: None, @@ -27,7 +27,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( diff --git a/crates/analyzer/tests/snapshots/analysis__ownable.snap b/crates/analyzer/tests/snapshots/analysis__ownable.snap index ea713a2d02..1fbbe6ac55 100644 --- a/crates/analyzer/tests/snapshots/analysis__ownable.snap +++ b/crates/analyzer/tests/snapshots/analysis__ownable.snap @@ -55,11 +55,11 @@ note: note: ┌─ ownable.fe:16:3 │ -16 │ ╭ pub fn renounceOwnership(mut self, ctx: Context): +16 │ ╭ pub fn renounceOwnership(mut self, mut ctx: Context): 17 │ │ assert ctx.msg_sender() == self._owner 18 │ │ self._owner = address(0) 19 │ │ emit OwnershipTransferred(ctx, previousOwner: ctx.msg_sender(), newOwner: address(0)) - │ ╰─────────────────────────────────────────────────────────────────────────────────────────^ attributes hash: 15898452962760116643 + │ ╰─────────────────────────────────────────────────────────────────────────────────────────^ attributes hash: 11556562928068896128 │ = FunctionSignature { self_decl: Some( @@ -73,7 +73,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -186,18 +186,18 @@ note: note: ┌─ ownable.fe:21:3 │ -21 │ ╭ pub fn transferOwnership(mut self, ctx: Context, newOwner: address): +21 │ ╭ pub fn transferOwnership(mut self, mut ctx: Context, newOwner: address): 22 │ │ assert ctx.msg_sender() == self._owner 23 │ │ assert newOwner != address(0) 24 │ │ self._owner = newOwner 25 │ │ emit OwnershipTransferred(ctx, previousOwner: ctx.msg_sender(), newOwner) - │ ╰─────────────────────────────────────────────────────────────────────────────^ attributes hash: 14397139561406753900 + │ ╰─────────────────────────────────────────────────────────────────────────────^ attributes hash: 7310417539232540001 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 534..538, + span: 538..542, }, ), ctx_decl: Some( @@ -205,7 +205,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( diff --git a/crates/analyzer/tests/snapshots/analysis__sized_vals_in_sto.snap b/crates/analyzer/tests/snapshots/analysis__sized_vals_in_sto.snap index 6c82c822ab..014faa3fec 100644 --- a/crates/analyzer/tests/snapshots/analysis__sized_vals_in_sto.snap +++ b/crates/analyzer/tests/snapshots/analysis__sized_vals_in_sto.snap @@ -305,14 +305,14 @@ note: note: ┌─ sized_vals_in_sto.fe:31:5 │ -31 │ ╭ pub fn emit_event(self, ctx: Context): +31 │ ╭ pub fn emit_event(self, mut ctx: Context): 32 │ │ emit MyEvent( 33 │ │ ctx, 34 │ │ num: self.num, 35 │ │ nums: self.nums.to_mem(), 36 │ │ str: self.str.to_mem() 37 │ │ ) - │ ╰─────────^ attributes hash: 10599346875189913769 + │ ╰─────────^ attributes hash: 9027717158627093145 │ = FunctionSignature { self_decl: Some( @@ -326,7 +326,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( diff --git a/crates/analyzer/tests/snapshots/analysis__tuple_stress.snap b/crates/analyzer/tests/snapshots/analysis__tuple_stress.snap index 099eaedb32..e7573784cc 100644 --- a/crates/analyzer/tests/snapshots/analysis__tuple_stress.snap +++ b/crates/analyzer/tests/snapshots/analysis__tuple_stress.snap @@ -366,9 +366,9 @@ note: note: ┌─ tuple_stress.fe:28:5 │ -28 │ ╭ pub fn emit_my_event(ctx: Context, my_tuple: (u256, bool, address)): +28 │ ╭ pub fn emit_my_event(mut ctx: Context, my_tuple: (u256, bool, address)): 29 │ │ emit MyEvent(ctx, my_tuple) - │ ╰───────────────────────────────────^ attributes hash: 8500762958207449372 + │ ╰───────────────────────────────────^ attributes hash: 11025609152955346579 │ = FunctionSignature { self_decl: None, @@ -377,7 +377,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -470,13 +470,13 @@ note: 31 │ ╭ pub fn set_my_sto_tuple(mut self, my_u256: u256, my_i32: i32): 32 │ │ assert self.my_sto_tuple.item0 == u256(0) and self.my_sto_tuple.item1 == i32(0) 33 │ │ self.my_sto_tuple = (my_u256, my_i32) - │ ╰─────────────────────────────────────────────^ attributes hash: 9638530552934349387 + │ ╰─────────────────────────────────────────────^ attributes hash: 8439468136978160381 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 924..928, + span: 928..932, }, ), ctx_decl: None, @@ -601,13 +601,13 @@ note: │ 35 │ ╭ pub fn get_my_sto_tuple(self) -> (u256, i32): 36 │ │ return self.my_sto_tuple.to_mem() - │ ╰─────────────────────────────────────────^ attributes hash: 16151200552390194455 + │ ╰─────────────────────────────────────────^ attributes hash: 16155991377237846637 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 1122..1126, + span: 1126..1130, }, ), ctx_decl: None, @@ -653,20 +653,20 @@ note: note: ┌─ tuple_stress.fe:38:5 │ -38 │ ╭ pub fn build_tuple_and_emit(self, ctx: Context): +38 │ ╭ pub fn build_tuple_and_emit(self, mut ctx: Context): 39 │ │ let my_num: u256 = self.my_sto_tuple.item0 40 │ │ let my_tuple: (u256, bool, address) = ( 41 │ │ self.my_sto_tuple.item0, · │ 44 │ │ ) 45 │ │ emit_my_event(ctx, my_tuple) - │ ╰────────────────────────────────────^ attributes hash: 16910797897652616193 + │ ╰────────────────────────────────────^ attributes hash: 9739511022859290279 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 1219..1223, + span: 1223..1227, }, ), ctx_decl: Some( @@ -674,7 +674,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( diff --git a/crates/analyzer/tests/snapshots/analysis__two_contracts.snap b/crates/analyzer/tests/snapshots/analysis__two_contracts.snap index f7a72b8ea5..cb932aa76d 100644 --- a/crates/analyzer/tests/snapshots/analysis__two_contracts.snap +++ b/crates/analyzer/tests/snapshots/analysis__two_contracts.snap @@ -163,9 +163,9 @@ note: note: ┌─ two_contracts.fe:19:5 │ -19 │ ╭ pub fn set_foo_addr(mut self, ctx: Context, _ addr: address): -20 │ │ self.other = Foo(ctx, addr) - │ ╰───────────────────────────────────^ attributes hash: 7772662931551478644 +19 │ ╭ pub fn set_foo_addr(mut self, _ addr: address): +20 │ │ self.other = Foo(addr) + │ ╰──────────────────────────────^ attributes hash: 9196615678677222113 │ = FunctionSignature { self_decl: Some( @@ -174,23 +174,8 @@ note: span: 401..405, }, ), - ctx_decl: Some( - Mutable, - ), + ctx_decl: None, params: [ - FunctionParam { - is_mut: false, - label: None, - name: "ctx", - typ: Ok( - Struct( - Struct { - name: "Context", - field_count: 0, - }, - ), - ), - }, FunctionParam { is_mut: false, label: Some( @@ -214,36 +199,35 @@ note: note: ┌─ two_contracts.fe:20:9 │ -20 │ self.other = Foo(ctx, addr) +20 │ self.other = Foo(addr) │ ^^^^ Bar: Value note: ┌─ two_contracts.fe:20:9 │ -20 │ self.other = Foo(ctx, addr) - │ ^^^^^^^^^^ ^^^ ^^^^ address: Value - │ │ │ - │ │ Context: Memory +20 │ self.other = Foo(addr) + │ ^^^^^^^^^^ ^^^^ address: Value + │ │ │ Foo: Storage { nonce: Some(0) } note: ┌─ two_contracts.fe:20:22 │ -20 │ self.other = Foo(ctx, addr) - │ ^^^^^^^^^^^^^^ Foo: Value +20 │ self.other = Foo(addr) + │ ^^^^^^^^^ Foo: Value note: ┌─ two_contracts.fe:22:5 │ 22 │ ╭ pub fn answer(self) -> u256: 23 │ │ return self.other.add(20, 22) - │ ╰─────────────────────────────────────^ attributes hash: 11070438767694404534 + │ ╰─────────────────────────────────────^ attributes hash: 16606523123636099115 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 494..498, + span: 475..479, }, ), ctx_decl: None, diff --git a/crates/analyzer/tests/snapshots/analysis__uniswap.snap b/crates/analyzer/tests/snapshots/analysis__uniswap.snap index e75ee444bb..cc7271c56f 100644 --- a/crates/analyzer/tests/snapshots/analysis__uniswap.snap +++ b/crates/analyzer/tests/snapshots/analysis__uniswap.snap @@ -6,12 +6,17 @@ expression: "build_snapshot(&db, module)" note: ┌─ uniswap.fe:4:5 │ -4 │ ╭ pub fn balanceOf(_ account: address) -> u256: +4 │ ╭ pub fn balanceOf(self, _ account: address) -> u256: 5 │ │ return 0 - │ ╰────────────────^ attributes hash: 15536516206350149884 + │ ╰────────────────^ attributes hash: 12180661080520285200 │ = FunctionSignature { - self_decl: None, + self_decl: Some( + SelfDecl { + kind: Ref, + span: 64..68, + }, + ), ctx_decl: None, params: [ FunctionParam { @@ -45,14 +50,29 @@ note: note: ┌─ uniswap.fe:7:5 │ -7 │ ╭ pub fn transfer(to: address, _ amount: u256) -> bool: +7 │ ╭ pub fn transfer(mut ctx: Context, to: address, _ amount: u256) -> bool: 8 │ │ return false - │ ╰────────────────────^ attributes hash: 12085341657079846741 + │ ╰────────────────────^ attributes hash: 11778738222858423657 │ = FunctionSignature { self_decl: None, - ctx_decl: None, + ctx_decl: Some( + Mutable, + ), params: [ + FunctionParam { + is_mut: true, + label: None, + name: "ctx", + typ: Ok( + Struct( + Struct { + name: "Context", + field_count: 0, + }, + ), + ), + }, FunctionParam { is_mut: false, label: None, @@ -196,13 +216,13 @@ note: │ 68 │ ╭ pub fn factory(self) -> address: 69 │ │ return self.factory - │ ╰───────────────────────────^ attributes hash: 3883682654554824383 + │ ╰───────────────────────────^ attributes hash: 14999444340663761907 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 1412..1416, + span: 1436..1440, }, ), ctx_decl: None, @@ -231,13 +251,13 @@ note: │ 71 │ ╭ pub fn token0(self) -> address: 72 │ │ return self.token0 - │ ╰──────────────────────────^ attributes hash: 12453447202682215801 + │ ╰──────────────────────────^ attributes hash: 12032505794870208787 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 1477..1481, + span: 1501..1505, }, ), ctx_decl: None, @@ -266,13 +286,13 @@ note: │ 74 │ ╭ pub fn token1(self) -> address: 75 │ │ return self.token1 - │ ╰──────────────────────────^ attributes hash: 609876714974830132 + │ ╰──────────────────────────^ attributes hash: 13930789323269584045 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 1541..1545, + span: 1565..1569, }, ), ctx_decl: None, @@ -299,17 +319,17 @@ note: note: ┌─ uniswap.fe:77:5 │ -77 │ ╭ fn _mint(mut self, ctx: Context, to: address, value: u256): +77 │ ╭ fn _mint(mut self, mut ctx: Context, to: address, value: u256): 78 │ │ self.total_supply = self.total_supply + value 79 │ │ self.balances[to] = self.balances[to] + value 80 │ │ emit Transfer(ctx, from: address(0), to, value) - │ ╰───────────────────────────────────────────────────────^ attributes hash: 2838731223825333376 + │ ╰───────────────────────────────────────────────────────^ attributes hash: 5114760941691894064 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 1604..1608, + span: 1628..1632, }, ), ctx_decl: Some( @@ -317,7 +337,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -484,17 +504,17 @@ note: note: ┌─ uniswap.fe:82:5 │ -82 │ ╭ fn _burn(mut self, ctx: Context, from: address, value: u256): +82 │ ╭ fn _burn(mut self, mut ctx: Context, from: address, value: u256): 83 │ │ self.balances[from] = self.balances[from] - value 84 │ │ self.total_supply = self.total_supply - value 85 │ │ emit Transfer(ctx, from, to: address(0), value) - │ ╰───────────────────────────────────────────────────────^ attributes hash: 4093973936631334187 + │ ╰───────────────────────────────────────────────────────^ attributes hash: 8864341459186458159 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 1833..1837, + span: 1861..1865, }, ), ctx_decl: Some( @@ -502,7 +522,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -669,16 +689,16 @@ note: note: ┌─ uniswap.fe:88:5 │ -88 │ ╭ fn _approve(mut self, ctx: Context, owner: address, spender: address, value: u256): +88 │ ╭ fn _approve(mut self, mut ctx: Context, owner: address, spender: address, value: u256): 89 │ │ self.allowances[owner][spender] = value 90 │ │ emit Approval(ctx, owner, spender, value) - │ ╰─────────────────────────────────────────────────^ attributes hash: 15735622105416244689 + │ ╰─────────────────────────────────────────────────^ attributes hash: 15443338293894883177 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 2072..2076, + span: 2104..2108, }, ), ctx_decl: Some( @@ -686,7 +706,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -818,17 +838,17 @@ note: note: ┌─ uniswap.fe:93:5 │ -93 │ ╭ fn _transfer(mut self, ctx: Context, from: address, to: address, value: u256): +93 │ ╭ fn _transfer(mut self, mut ctx: Context, from: address, to: address, value: u256): 94 │ │ self.balances[from] = self.balances[from] - value 95 │ │ self.balances[to] = self.balances[to] + value 96 │ │ emit Transfer(ctx, from, to, value) - │ ╰───────────────────────────────────────────^ attributes hash: 12485952734392732060 + │ ╰───────────────────────────────────────────^ attributes hash: 5983886735283377960 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 2261..2265, + span: 2297..2301, }, ), ctx_decl: Some( @@ -836,7 +856,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -1022,16 +1042,16 @@ note: note: ┌─ uniswap.fe:98:5 │ - 98 │ ╭ pub fn approve(mut self, ctx: Context, spender: address, value: u256) -> bool: + 98 │ ╭ pub fn approve(mut self, mut ctx: Context, spender: address, value: u256) -> bool: 99 │ │ self._approve(ctx, owner: ctx.msg_sender(), spender, value) 100 │ │ return true - │ ╰───────────────────^ attributes hash: 15682368485749544822 + │ ╰───────────────────^ attributes hash: 467824196490947536 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 2503..2507, + span: 2543..2547, }, ), ctx_decl: Some( @@ -1039,7 +1059,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -1110,16 +1130,16 @@ note: note: ┌─ uniswap.fe:102:5 │ -102 │ ╭ pub fn transfer(mut self, ctx: Context, to: address, value: u256) -> bool: +102 │ ╭ pub fn transfer(mut self, mut ctx: Context, to: address, value: u256) -> bool: 103 │ │ self._transfer(ctx, from: ctx.msg_sender(), to, value) 104 │ │ return true - │ ╰───────────────────^ attributes hash: 1505213770801861479 + │ ╰───────────────────^ attributes hash: 4528968593415249654 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 2676..2680, + span: 2720..2724, }, ), ctx_decl: Some( @@ -1127,7 +1147,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -1198,18 +1218,18 @@ note: note: ┌─ uniswap.fe:106:5 │ -106 │ ╭ pub fn transferFrom(mut self, ctx: Context, from: address, to: address, value: u256) -> bool: +106 │ ╭ pub fn transferFrom(mut self, mut ctx: Context, from: address, to: address, value: u256) -> bool: 107 │ │ assert self.allowances[from][ctx.msg_sender()] >= value 108 │ │ self.allowances[from][ctx.msg_sender()] = self.allowances[from][ctx.msg_sender()] - value 109 │ │ self._transfer(ctx, from, to, value) 110 │ │ return true - │ ╰───────────────────^ attributes hash: 15014414441315333161 + │ ╰───────────────────^ attributes hash: 12453372281879953233 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 2843..2847, + span: 2891..2895, }, ), ctx_decl: Some( @@ -1217,7 +1237,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -1399,13 +1419,13 @@ note: │ 112 │ ╭ pub fn balanceOf(self, _ account: address) -> u256: 113 │ │ return self.balances[account] - │ ╰─────────────────────────────────────^ attributes hash: 14778835780928648959 + │ ╰─────────────────────────────────────^ attributes hash: 14488488730713390740 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 3162..3166, + span: 3214..3218, }, ), ctx_decl: None, @@ -1457,13 +1477,13 @@ note: │ 115 │ ╭ pub fn get_reserves(self) -> (u256, u256, u256): 116 │ │ return (self.reserve0, self.reserve1, self.block_timestamp_last) - │ ╰────────────────────────────────────────────────────────────────────────^ attributes hash: 8579517199767811469 + │ ╰────────────────────────────────────────────────────────────────────────^ attributes hash: 11667458651469489759 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 3260..3264, + span: 3312..3316, }, ), ctx_decl: None, @@ -1534,13 +1554,13 @@ note: 120 │ │ assert ctx.msg_sender() == self.factory, "UniswapV2: FORBIDDEN" 121 │ │ self.token0 = token0 122 │ │ self.token1 = token1 - │ ╰────────────────────────────^ attributes hash: 1457888239674380142 + │ ╰────────────────────────────^ attributes hash: 7810866460916963443 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 3444..3448, + span: 3496..3500, }, ), ctx_decl: Some( @@ -1639,20 +1659,20 @@ note: note: ┌─ uniswap.fe:125:5 │ -125 │ ╭ fn _update(mut self, ctx: Context, balance0: u256, balance1: u256, reserve0: u256, reserve1: u256): +125 │ ╭ fn _update(mut self, mut ctx: Context, balance0: u256, balance1: u256, reserve0: u256, reserve1: u256): 126 │ │ # changed from u32s 127 │ │ let block_timestamp: u256 = ctx.block_timestamp() % 2**32 128 │ │ # TODO: reproduce desired overflow (https://github.com/ethereum/fe/issues/286) · │ 137 │ │ self.block_timestamp_last = block_timestamp 138 │ │ emit Sync(ctx, reserve0: self.reserve0, reserve1: self.reserve1) - │ ╰────────────────────────────────────────────────────────────────────────^ attributes hash: 1767704501231443649 + │ ╰────────────────────────────────────────────────────────────────────────^ attributes hash: 16258128246703972623 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 3724..3728, + span: 3776..3780, }, ), ctx_decl: Some( @@ -1660,7 +1680,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -1986,20 +2006,20 @@ note: note: ┌─ uniswap.fe:141:5 │ -141 │ ╭ fn _mint_fee(mut self, ctx: Context, reserve0: u256, reserve1: u256) -> bool: -142 │ │ let fee_to: address = UniswapV2Factory(ctx, self.factory).fee_to() +141 │ ╭ fn _mint_fee(mut self, mut ctx: Context, reserve0: u256, reserve1: u256) -> bool: +142 │ │ let fee_to: address = UniswapV2Factory(self.factory).fee_to() 143 │ │ let fee_on: bool = fee_to != address(0) 144 │ │ let k_last: u256 = self.k_last # gas savings · │ 157 │ │ 158 │ │ return fee_on - │ ╰─────────────────────^ attributes hash: 5237904610411090364 + │ ╰─────────────────────^ attributes hash: 11980814949583935709 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 4727..4731, + span: 4783..4787, }, ), ctx_decl: Some( @@ -2007,7 +2027,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -2054,7 +2074,7 @@ note: note: ┌─ uniswap.fe:142:21 │ -142 │ let fee_to: address = UniswapV2Factory(ctx, self.factory).fee_to() +142 │ let fee_to: address = UniswapV2Factory(self.factory).fee_to() │ ^^^^^^^ address 143 │ let fee_on: bool = fee_to != address(0) │ ^^^^ bool @@ -2076,28 +2096,26 @@ note: note: ┌─ uniswap.fe:142:48 │ -142 │ let fee_to: address = UniswapV2Factory(ctx, self.factory).fee_to() - │ ^^^ ^^^^ UniswapV2Pair: Value - │ │ - │ Context: Memory +142 │ let fee_to: address = UniswapV2Factory(self.factory).fee_to() + │ ^^^^ UniswapV2Pair: Value note: - ┌─ uniswap.fe:142:53 + ┌─ uniswap.fe:142:48 │ -142 │ let fee_to: address = UniswapV2Factory(ctx, self.factory).fee_to() - │ ^^^^^^^^^^^^ address: Storage { nonce: Some(4) } => Value +142 │ let fee_to: address = UniswapV2Factory(self.factory).fee_to() + │ ^^^^^^^^^^^^ address: Storage { nonce: Some(4) } => Value note: ┌─ uniswap.fe:142:31 │ -142 │ let fee_to: address = UniswapV2Factory(ctx, self.factory).fee_to() - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UniswapV2Factory: Value +142 │ let fee_to: address = UniswapV2Factory(self.factory).fee_to() + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UniswapV2Factory: Value note: ┌─ uniswap.fe:142:31 │ -142 │ let fee_to: address = UniswapV2Factory(ctx, self.factory).fee_to() - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ address: Value +142 │ let fee_to: address = UniswapV2Factory(self.factory).fee_to() + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ address: Value 143 │ let fee_on: bool = fee_to != address(0) │ ^^^^^^ ^ u256: Value │ │ @@ -2269,20 +2287,20 @@ note: note: ┌─ uniswap.fe:161:5 │ -161 │ ╭ pub fn mint(mut self, ctx: Context, to: address) -> u256: +161 │ ╭ pub fn mint(mut self, mut ctx: Context, to: address) -> u256: 162 │ │ let MINIMUM_LIQUIDITY: u256 = 1000 163 │ │ let reserve0: u256 = self.reserve0 164 │ │ let reserve1: u256 = self.reserve1 · │ 187 │ │ emit Mint(ctx, sender: ctx.msg_sender(), amount0, amount1) 188 │ │ return liquidity - │ ╰────────────────────────^ attributes hash: 4920140949246745606 + │ ╰────────────────────────^ attributes hash: 1540623132326392785 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 5692..5696, + span: 5747..5751, }, ), ctx_decl: Some( @@ -2290,7 +2308,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -2331,9 +2349,9 @@ note: │ ^^^^ u256 164 │ let reserve1: u256 = self.reserve1 │ ^^^^ u256 -165 │ let balance0: u256 = ERC20(ctx, self.token0).balanceOf(ctx.self_address()) +165 │ let balance0: u256 = ERC20(self.token0).balanceOf(ctx.self_address()) │ ^^^^ u256 -166 │ let balance1: u256 = ERC20(ctx, self.token1).balanceOf(ctx.self_address()) +166 │ let balance1: u256 = ERC20(self.token1).balanceOf(ctx.self_address()) │ ^^^^ u256 167 │ let amount0: u256 = balance0 - self.reserve0 │ ^^^^ u256 @@ -2368,66 +2386,62 @@ note: │ 164 │ let reserve1: u256 = self.reserve1 │ ^^^^^^^^^^^^^ u256: Storage { nonce: Some(8) } => Value -165 │ let balance0: u256 = ERC20(ctx, self.token0).balanceOf(ctx.self_address()) - │ ^^^ ^^^^ UniswapV2Pair: Value - │ │ - │ Context: Memory +165 │ let balance0: u256 = ERC20(self.token0).balanceOf(ctx.self_address()) + │ ^^^^ UniswapV2Pair: Value note: - ┌─ uniswap.fe:165:41 + ┌─ uniswap.fe:165:36 │ -165 │ let balance0: u256 = ERC20(ctx, self.token0).balanceOf(ctx.self_address()) - │ ^^^^^^^^^^^ address: Storage { nonce: Some(5) } => Value +165 │ let balance0: u256 = ERC20(self.token0).balanceOf(ctx.self_address()) + │ ^^^^^^^^^^^ address: Storage { nonce: Some(5) } => Value note: ┌─ uniswap.fe:165:30 │ -165 │ let balance0: u256 = ERC20(ctx, self.token0).balanceOf(ctx.self_address()) - │ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^ Context: Memory - │ │ +165 │ let balance0: u256 = ERC20(self.token0).balanceOf(ctx.self_address()) + │ ^^^^^^^^^^^^^^^^^^ ^^^ Context: Memory + │ │ │ ERC20: Value note: - ┌─ uniswap.fe:165:64 + ┌─ uniswap.fe:165:59 │ -165 │ let balance0: u256 = ERC20(ctx, self.token0).balanceOf(ctx.self_address()) - │ ^^^^^^^^^^^^^^^^^^ address: Value +165 │ let balance0: u256 = ERC20(self.token0).balanceOf(ctx.self_address()) + │ ^^^^^^^^^^^^^^^^^^ address: Value note: ┌─ uniswap.fe:165:30 │ -165 │ let balance0: u256 = ERC20(ctx, self.token0).balanceOf(ctx.self_address()) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u256: Value -166 │ let balance1: u256 = ERC20(ctx, self.token1).balanceOf(ctx.self_address()) - │ ^^^ ^^^^ UniswapV2Pair: Value - │ │ - │ Context: Memory +165 │ let balance0: u256 = ERC20(self.token0).balanceOf(ctx.self_address()) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u256: Value +166 │ let balance1: u256 = ERC20(self.token1).balanceOf(ctx.self_address()) + │ ^^^^ UniswapV2Pair: Value note: - ┌─ uniswap.fe:166:41 + ┌─ uniswap.fe:166:36 │ -166 │ let balance1: u256 = ERC20(ctx, self.token1).balanceOf(ctx.self_address()) - │ ^^^^^^^^^^^ address: Storage { nonce: Some(6) } => Value +166 │ let balance1: u256 = ERC20(self.token1).balanceOf(ctx.self_address()) + │ ^^^^^^^^^^^ address: Storage { nonce: Some(6) } => Value note: ┌─ uniswap.fe:166:30 │ -166 │ let balance1: u256 = ERC20(ctx, self.token1).balanceOf(ctx.self_address()) - │ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^ Context: Memory - │ │ +166 │ let balance1: u256 = ERC20(self.token1).balanceOf(ctx.self_address()) + │ ^^^^^^^^^^^^^^^^^^ ^^^ Context: Memory + │ │ │ ERC20: Value note: - ┌─ uniswap.fe:166:64 + ┌─ uniswap.fe:166:59 │ -166 │ let balance1: u256 = ERC20(ctx, self.token1).balanceOf(ctx.self_address()) - │ ^^^^^^^^^^^^^^^^^^ address: Value +166 │ let balance1: u256 = ERC20(self.token1).balanceOf(ctx.self_address()) + │ ^^^^^^^^^^^^^^^^^^ address: Value note: ┌─ uniswap.fe:166:30 │ -166 │ let balance1: u256 = ERC20(ctx, self.token1).balanceOf(ctx.self_address()) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u256: Value +166 │ let balance1: u256 = ERC20(self.token1).balanceOf(ctx.self_address()) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u256: Value 167 │ let amount0: u256 = balance0 - self.reserve0 │ ^^^^^^^^ ^^^^ UniswapV2Pair: Value │ │ @@ -2703,20 +2717,20 @@ note: note: ┌─ uniswap.fe:191:5 │ -191 │ ╭ pub fn burn(mut self, ctx: Context, to: address) -> (u256, u256): +191 │ ╭ pub fn burn(mut self, mut ctx: Context, to: address) -> (u256, u256): 192 │ │ let reserve0: u256 = self.reserve0 193 │ │ let reserve1: u256 = self.reserve1 -194 │ │ let token0: ERC20 = ERC20(ctx, self.token0) +194 │ │ let token0: ERC20 = ERC20(self.token0) · │ 216 │ │ emit Burn(ctx, sender: ctx.msg_sender(), amount0, amount1, to) 217 │ │ return (amount0, amount1) - │ ╰─────────────────────────────────^ attributes hash: 9480812542525876292 + │ ╰─────────────────────────────────^ attributes hash: 13713787040542998263 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 7213..7217, + span: 7262..7266, }, ), ctx_decl: Some( @@ -2724,7 +2738,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -2774,9 +2788,9 @@ note: │ ^^^^ u256 193 │ let reserve1: u256 = self.reserve1 │ ^^^^ u256 -194 │ let token0: ERC20 = ERC20(ctx, self.token0) +194 │ let token0: ERC20 = ERC20(self.token0) │ ^^^^^ ERC20 -195 │ let token1: ERC20 = ERC20(ctx, self.token1) +195 │ let token1: ERC20 = ERC20(self.token1) │ ^^^^^ ERC20 196 │ let mut balance0: u256 = token0.balanceOf(ctx.self_address()) │ ^^^^ u256 @@ -2813,38 +2827,34 @@ note: │ 193 │ let reserve1: u256 = self.reserve1 │ ^^^^^^^^^^^^^ u256: Storage { nonce: Some(8) } => Value -194 │ let token0: ERC20 = ERC20(ctx, self.token0) - │ ^^^ ^^^^ UniswapV2Pair: Value - │ │ - │ Context: Memory +194 │ let token0: ERC20 = ERC20(self.token0) + │ ^^^^ UniswapV2Pair: Value note: - ┌─ uniswap.fe:194:40 + ┌─ uniswap.fe:194:35 │ -194 │ let token0: ERC20 = ERC20(ctx, self.token0) - │ ^^^^^^^^^^^ address: Storage { nonce: Some(5) } => Value +194 │ let token0: ERC20 = ERC20(self.token0) + │ ^^^^^^^^^^^ address: Storage { nonce: Some(5) } => Value note: ┌─ uniswap.fe:194:29 │ -194 │ let token0: ERC20 = ERC20(ctx, self.token0) - │ ^^^^^^^^^^^^^^^^^^^^^^^ ERC20: Value -195 │ let token1: ERC20 = ERC20(ctx, self.token1) - │ ^^^ ^^^^ UniswapV2Pair: Value - │ │ - │ Context: Memory +194 │ let token0: ERC20 = ERC20(self.token0) + │ ^^^^^^^^^^^^^^^^^^ ERC20: Value +195 │ let token1: ERC20 = ERC20(self.token1) + │ ^^^^ UniswapV2Pair: Value note: - ┌─ uniswap.fe:195:40 + ┌─ uniswap.fe:195:35 │ -195 │ let token1: ERC20 = ERC20(ctx, self.token1) - │ ^^^^^^^^^^^ address: Storage { nonce: Some(6) } => Value +195 │ let token1: ERC20 = ERC20(self.token1) + │ ^^^^^^^^^^^ address: Storage { nonce: Some(6) } => Value note: ┌─ uniswap.fe:195:29 │ -195 │ let token1: ERC20 = ERC20(ctx, self.token1) - │ ^^^^^^^^^^^^^^^^^^^^^^^ ERC20: Value +195 │ let token1: ERC20 = ERC20(self.token1) + │ ^^^^^^^^^^^^^^^^^^ ERC20: Value 196 │ let mut balance0: u256 = token0.balanceOf(ctx.self_address()) │ ^^^^^^ ^^^ Context: Memory │ │ @@ -3002,28 +3012,30 @@ note: │ 205 │ self._burn(ctx, from: ctx.self_address(), value: liquidity) │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (): Value -206 │ token0.transfer(to, amount0) - │ ^^^^^^ ^^ ^^^^^^^ u256: Value - │ │ │ - │ │ address: Value +206 │ token0.transfer(ctx, to, amount0) + │ ^^^^^^ ^^^ ^^ ^^^^^^^ u256: Value + │ │ │ │ + │ │ │ address: Value + │ │ Context: Memory │ ERC20: Value note: ┌─ uniswap.fe:206:9 │ -206 │ token0.transfer(to, amount0) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value -207 │ token1.transfer(to, amount1) - │ ^^^^^^ ^^ ^^^^^^^ u256: Value - │ │ │ - │ │ address: Value +206 │ token0.transfer(ctx, to, amount0) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value +207 │ token1.transfer(ctx, to, amount1) + │ ^^^^^^ ^^^ ^^ ^^^^^^^ u256: Value + │ │ │ │ + │ │ │ address: Value + │ │ Context: Memory │ ERC20: Value note: ┌─ uniswap.fe:207:9 │ -207 │ token1.transfer(to, amount1) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value +207 │ token1.transfer(ctx, to, amount1) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value 208 │ balance0 = token0.balanceOf(ctx.self_address()) │ ^^^^^^^^ ^^^^^^ ^^^ Context: Memory │ │ │ @@ -3174,20 +3186,20 @@ note: note: ┌─ uniswap.fe:222:5 │ -222 │ ╭ pub fn swap(mut self, ctx: Context, amount0_out: u256, amount1_out: u256, to: address): +222 │ ╭ pub fn swap(mut self, mut ctx: Context, amount0_out: u256, amount1_out: u256, to: address): 223 │ │ assert amount0_out > 0 or amount1_out > 0, "UniswapV2: INSUFFICIENT_OUTPUT_AMOUNT" 224 │ │ let reserve0: u256 = self.reserve0 225 │ │ let reserve1: u256 = self.reserve1 · │ 255 │ │ self._update(ctx, balance0, balance1, reserve0, reserve1) 256 │ │ emit Swap(ctx, sender: ctx.msg_sender(), amount0_in, amount1_in, amount0_out, amount1_out, to) - │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────^ attributes hash: 2939999212869493409 + │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────^ attributes hash: 10648804797280558990 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 8992..8996, + span: 9045..9049, }, ), ctx_decl: Some( @@ -3195,7 +3207,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -3257,9 +3269,9 @@ note: 225 │ let reserve1: u256 = self.reserve1 │ ^^^^ u256 · -228 │ let token0: ERC20 = ERC20(ctx, self.token0) +228 │ let token0: ERC20 = ERC20(self.token0) │ ^^^^^ ERC20 -229 │ let token1: ERC20 = ERC20(ctx, self.token1) +229 │ let token1: ERC20 = ERC20(self.token1) │ ^^^^^ ERC20 · 242 │ let balance0: u256 = token0.balanceOf(ctx.self_address()) @@ -3351,38 +3363,34 @@ note: │ │ │ bool: Value 227 │ -228 │ let token0: ERC20 = ERC20(ctx, self.token0) - │ ^^^ ^^^^ UniswapV2Pair: Value - │ │ - │ Context: Memory +228 │ let token0: ERC20 = ERC20(self.token0) + │ ^^^^ UniswapV2Pair: Value note: - ┌─ uniswap.fe:228:40 + ┌─ uniswap.fe:228:35 │ -228 │ let token0: ERC20 = ERC20(ctx, self.token0) - │ ^^^^^^^^^^^ address: Storage { nonce: Some(5) } => Value +228 │ let token0: ERC20 = ERC20(self.token0) + │ ^^^^^^^^^^^ address: Storage { nonce: Some(5) } => Value note: ┌─ uniswap.fe:228:29 │ -228 │ let token0: ERC20 = ERC20(ctx, self.token0) - │ ^^^^^^^^^^^^^^^^^^^^^^^ ERC20: Value -229 │ let token1: ERC20 = ERC20(ctx, self.token1) - │ ^^^ ^^^^ UniswapV2Pair: Value - │ │ - │ Context: Memory +228 │ let token0: ERC20 = ERC20(self.token0) + │ ^^^^^^^^^^^^^^^^^^ ERC20: Value +229 │ let token1: ERC20 = ERC20(self.token1) + │ ^^^^ UniswapV2Pair: Value note: - ┌─ uniswap.fe:229:40 + ┌─ uniswap.fe:229:35 │ -229 │ let token1: ERC20 = ERC20(ctx, self.token1) - │ ^^^^^^^^^^^ address: Storage { nonce: Some(6) } => Value +229 │ let token1: ERC20 = ERC20(self.token1) + │ ^^^^^^^^^^^ address: Storage { nonce: Some(6) } => Value note: ┌─ uniswap.fe:229:29 │ -229 │ let token1: ERC20 = ERC20(ctx, self.token1) - │ ^^^^^^^^^^^^^^^^^^^^^^^ ERC20: Value +229 │ let token1: ERC20 = ERC20(self.token1) + │ ^^^^^^^^^^^^^^^^^^ ERC20: Value · 232 │ assert to != address(token0) and to != address(token1), "UniswapV2: INVALID_TO" │ ^^ ^^^^^^ ERC20: Value @@ -3434,17 +3442,18 @@ note: │ 234 │ if amount0_out > 0: │ ^^^^^^^^^^^^^^^ bool: Value -235 │ token0.transfer(to, amount0_out) # optimistically transfer tokens - │ ^^^^^^ ^^ ^^^^^^^^^^^ u256: Value - │ │ │ - │ │ address: Value +235 │ token0.transfer(ctx, to, amount0_out) # optimistically transfer tokens + │ ^^^^^^ ^^^ ^^ ^^^^^^^^^^^ u256: Value + │ │ │ │ + │ │ │ address: Value + │ │ Context: Memory │ ERC20: Value note: ┌─ uniswap.fe:235:13 │ -235 │ token0.transfer(to, amount0_out) # optimistically transfer tokens - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value +235 │ token0.transfer(ctx, to, amount0_out) # optimistically transfer tokens + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value 236 │ if amount1_out > 0: │ ^^^^^^^^^^^ ^ u256: Value │ │ @@ -3455,17 +3464,18 @@ note: │ 236 │ if amount1_out > 0: │ ^^^^^^^^^^^^^^^ bool: Value -237 │ token1.transfer(to, amount1_out) # optimistically transfer tokens - │ ^^^^^^ ^^ ^^^^^^^^^^^ u256: Value - │ │ │ - │ │ address: Value +237 │ token1.transfer(ctx, to, amount1_out) # optimistically transfer tokens + │ ^^^^^^ ^^^ ^^ ^^^^^^^^^^^ u256: Value + │ │ │ │ + │ │ │ address: Value + │ │ Context: Memory │ ERC20: Value note: ┌─ uniswap.fe:237:13 │ -237 │ token1.transfer(to, amount1_out) # optimistically transfer tokens - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value +237 │ token1.transfer(ctx, to, amount1_out) # optimistically transfer tokens + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value · 242 │ let balance0: u256 = token0.balanceOf(ctx.self_address()) │ ^^^^^^ ^^^ Context: Memory @@ -3818,19 +3828,19 @@ note: note: ┌─ uniswap.fe:259:5 │ -259 │ ╭ pub fn skim(mut self, ctx: Context, to: address): -260 │ │ let token0: ERC20 = ERC20(ctx, self.token0) # gas savings -261 │ │ let token1: ERC20 = ERC20(ctx, self.token1) # gas savings +259 │ ╭ pub fn skim(mut self, mut ctx: Context, to: address): +260 │ │ let token0: ERC20 = ERC20(self.token0) # gas savings +261 │ │ let token1: ERC20 = ERC20(self.token1) # gas savings 262 │ │ -263 │ │ token0.transfer(to, token0.balanceOf(ctx.self_address()) - self.reserve0) -264 │ │ token1.transfer(to, token1.balanceOf(ctx.self_address()) - self.reserve1) - │ ╰─────────────────────────────────────────────────────────────────────────────────^ attributes hash: 5316608983835287591 +263 │ │ token0.transfer(ctx, to, token0.balanceOf(ctx.self_address()) - self.reserve0) +264 │ │ token1.transfer(ctx, to, token1.balanceOf(ctx.self_address()) - self.reserve1) + │ ╰──────────────────────────────────────────────────────────────────────────────────────^ attributes hash: 1924301240711868448 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 10918..10922, + span: 10975..10979, }, ), ctx_decl: Some( @@ -3838,7 +3848,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -3871,141 +3881,139 @@ note: note: ┌─ uniswap.fe:260:21 │ -260 │ let token0: ERC20 = ERC20(ctx, self.token0) # gas savings +260 │ let token0: ERC20 = ERC20(self.token0) # gas savings │ ^^^^^ ERC20 -261 │ let token1: ERC20 = ERC20(ctx, self.token1) # gas savings +261 │ let token1: ERC20 = ERC20(self.token1) # gas savings │ ^^^^^ ERC20 note: ┌─ uniswap.fe:260:35 │ -260 │ let token0: ERC20 = ERC20(ctx, self.token0) # gas savings - │ ^^^ ^^^^ UniswapV2Pair: Value - │ │ - │ Context: Memory +260 │ let token0: ERC20 = ERC20(self.token0) # gas savings + │ ^^^^ UniswapV2Pair: Value note: - ┌─ uniswap.fe:260:40 + ┌─ uniswap.fe:260:35 │ -260 │ let token0: ERC20 = ERC20(ctx, self.token0) # gas savings - │ ^^^^^^^^^^^ address: Storage { nonce: Some(5) } => Value +260 │ let token0: ERC20 = ERC20(self.token0) # gas savings + │ ^^^^^^^^^^^ address: Storage { nonce: Some(5) } => Value note: ┌─ uniswap.fe:260:29 │ -260 │ let token0: ERC20 = ERC20(ctx, self.token0) # gas savings - │ ^^^^^^^^^^^^^^^^^^^^^^^ ERC20: Value -261 │ let token1: ERC20 = ERC20(ctx, self.token1) # gas savings - │ ^^^ ^^^^ UniswapV2Pair: Value - │ │ - │ Context: Memory +260 │ let token0: ERC20 = ERC20(self.token0) # gas savings + │ ^^^^^^^^^^^^^^^^^^ ERC20: Value +261 │ let token1: ERC20 = ERC20(self.token1) # gas savings + │ ^^^^ UniswapV2Pair: Value note: - ┌─ uniswap.fe:261:40 + ┌─ uniswap.fe:261:35 │ -261 │ let token1: ERC20 = ERC20(ctx, self.token1) # gas savings - │ ^^^^^^^^^^^ address: Storage { nonce: Some(6) } => Value +261 │ let token1: ERC20 = ERC20(self.token1) # gas savings + │ ^^^^^^^^^^^ address: Storage { nonce: Some(6) } => Value note: ┌─ uniswap.fe:261:29 │ -261 │ let token1: ERC20 = ERC20(ctx, self.token1) # gas savings - │ ^^^^^^^^^^^^^^^^^^^^^^^ ERC20: Value +261 │ let token1: ERC20 = ERC20(self.token1) # gas savings + │ ^^^^^^^^^^^^^^^^^^ ERC20: Value 262 │ -263 │ token0.transfer(to, token0.balanceOf(ctx.self_address()) - self.reserve0) - │ ^^^^^^ ^^ ^^^^^^ ^^^ Context: Memory - │ │ │ │ - │ │ │ ERC20: Value - │ │ address: Value +263 │ token0.transfer(ctx, to, token0.balanceOf(ctx.self_address()) - self.reserve0) + │ ^^^^^^ ^^^ ^^ ^^^^^^ ^^^ Context: Memory + │ │ │ │ │ + │ │ │ │ ERC20: Value + │ │ │ address: Value + │ │ Context: Memory │ ERC20: Value note: - ┌─ uniswap.fe:263:46 + ┌─ uniswap.fe:263:51 │ -263 │ token0.transfer(to, token0.balanceOf(ctx.self_address()) - self.reserve0) - │ ^^^^^^^^^^^^^^^^^^ address: Value +263 │ token0.transfer(ctx, to, token0.balanceOf(ctx.self_address()) - self.reserve0) + │ ^^^^^^^^^^^^^^^^^^ address: Value note: - ┌─ uniswap.fe:263:29 + ┌─ uniswap.fe:263:34 │ -263 │ token0.transfer(to, token0.balanceOf(ctx.self_address()) - self.reserve0) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ UniswapV2Pair: Value - │ │ - │ u256: Value +263 │ token0.transfer(ctx, to, token0.balanceOf(ctx.self_address()) - self.reserve0) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ UniswapV2Pair: Value + │ │ + │ u256: Value note: - ┌─ uniswap.fe:263:68 + ┌─ uniswap.fe:263:73 │ -263 │ token0.transfer(to, token0.balanceOf(ctx.self_address()) - self.reserve0) - │ ^^^^^^^^^^^^^ u256: Storage { nonce: Some(7) } => Value +263 │ token0.transfer(ctx, to, token0.balanceOf(ctx.self_address()) - self.reserve0) + │ ^^^^^^^^^^^^^ u256: Storage { nonce: Some(7) } => Value note: - ┌─ uniswap.fe:263:29 + ┌─ uniswap.fe:263:34 │ -263 │ token0.transfer(to, token0.balanceOf(ctx.self_address()) - self.reserve0) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u256: Value +263 │ token0.transfer(ctx, to, token0.balanceOf(ctx.self_address()) - self.reserve0) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u256: Value note: ┌─ uniswap.fe:263:9 │ -263 │ token0.transfer(to, token0.balanceOf(ctx.self_address()) - self.reserve0) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value -264 │ token1.transfer(to, token1.balanceOf(ctx.self_address()) - self.reserve1) - │ ^^^^^^ ^^ ^^^^^^ ^^^ Context: Memory - │ │ │ │ - │ │ │ ERC20: Value - │ │ address: Value +263 │ token0.transfer(ctx, to, token0.balanceOf(ctx.self_address()) - self.reserve0) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value +264 │ token1.transfer(ctx, to, token1.balanceOf(ctx.self_address()) - self.reserve1) + │ ^^^^^^ ^^^ ^^ ^^^^^^ ^^^ Context: Memory + │ │ │ │ │ + │ │ │ │ ERC20: Value + │ │ │ address: Value + │ │ Context: Memory │ ERC20: Value note: - ┌─ uniswap.fe:264:46 + ┌─ uniswap.fe:264:51 │ -264 │ token1.transfer(to, token1.balanceOf(ctx.self_address()) - self.reserve1) - │ ^^^^^^^^^^^^^^^^^^ address: Value +264 │ token1.transfer(ctx, to, token1.balanceOf(ctx.self_address()) - self.reserve1) + │ ^^^^^^^^^^^^^^^^^^ address: Value note: - ┌─ uniswap.fe:264:29 + ┌─ uniswap.fe:264:34 │ -264 │ token1.transfer(to, token1.balanceOf(ctx.self_address()) - self.reserve1) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ UniswapV2Pair: Value - │ │ - │ u256: Value +264 │ token1.transfer(ctx, to, token1.balanceOf(ctx.self_address()) - self.reserve1) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ UniswapV2Pair: Value + │ │ + │ u256: Value note: - ┌─ uniswap.fe:264:68 + ┌─ uniswap.fe:264:73 │ -264 │ token1.transfer(to, token1.balanceOf(ctx.self_address()) - self.reserve1) - │ ^^^^^^^^^^^^^ u256: Storage { nonce: Some(8) } => Value +264 │ token1.transfer(ctx, to, token1.balanceOf(ctx.self_address()) - self.reserve1) + │ ^^^^^^^^^^^^^ u256: Storage { nonce: Some(8) } => Value note: - ┌─ uniswap.fe:264:29 + ┌─ uniswap.fe:264:34 │ -264 │ token1.transfer(to, token1.balanceOf(ctx.self_address()) - self.reserve1) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u256: Value +264 │ token1.transfer(ctx, to, token1.balanceOf(ctx.self_address()) - self.reserve1) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u256: Value note: ┌─ uniswap.fe:264:9 │ -264 │ token1.transfer(to, token1.balanceOf(ctx.self_address()) - self.reserve1) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value +264 │ token1.transfer(ctx, to, token1.balanceOf(ctx.self_address()) - self.reserve1) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value note: ┌─ uniswap.fe:267:5 │ -267 │ ╭ pub fn sync(mut self, ctx: Context): -268 │ │ let token0: ERC20 = ERC20(ctx, self.token0) -269 │ │ let token1: ERC20 = ERC20(ctx, self.token1) +267 │ ╭ pub fn sync(mut self, mut ctx: Context): +268 │ │ let token0: ERC20 = ERC20(self.token0) +269 │ │ let token1: ERC20 = ERC20(self.token1) 270 │ │ self._update(ctx, · │ 273 │ │ reserve0: self.reserve0, 274 │ │ reserve1: self.reserve1) - │ ╰─────────────────────────────────────────────^ attributes hash: 10932442012863233492 + │ ╰─────────────────────────────────────────────^ attributes hash: 13232803038139673058 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 11309..11313, + span: 11370..11374, }, ), ctx_decl: Some( @@ -4013,7 +4021,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -4036,46 +4044,42 @@ note: note: ┌─ uniswap.fe:268:21 │ -268 │ let token0: ERC20 = ERC20(ctx, self.token0) +268 │ let token0: ERC20 = ERC20(self.token0) │ ^^^^^ ERC20 -269 │ let token1: ERC20 = ERC20(ctx, self.token1) +269 │ let token1: ERC20 = ERC20(self.token1) │ ^^^^^ ERC20 note: ┌─ uniswap.fe:268:35 │ -268 │ let token0: ERC20 = ERC20(ctx, self.token0) - │ ^^^ ^^^^ UniswapV2Pair: Value - │ │ - │ Context: Memory +268 │ let token0: ERC20 = ERC20(self.token0) + │ ^^^^ UniswapV2Pair: Value note: - ┌─ uniswap.fe:268:40 + ┌─ uniswap.fe:268:35 │ -268 │ let token0: ERC20 = ERC20(ctx, self.token0) - │ ^^^^^^^^^^^ address: Storage { nonce: Some(5) } => Value +268 │ let token0: ERC20 = ERC20(self.token0) + │ ^^^^^^^^^^^ address: Storage { nonce: Some(5) } => Value note: ┌─ uniswap.fe:268:29 │ -268 │ let token0: ERC20 = ERC20(ctx, self.token0) - │ ^^^^^^^^^^^^^^^^^^^^^^^ ERC20: Value -269 │ let token1: ERC20 = ERC20(ctx, self.token1) - │ ^^^ ^^^^ UniswapV2Pair: Value - │ │ - │ Context: Memory +268 │ let token0: ERC20 = ERC20(self.token0) + │ ^^^^^^^^^^^^^^^^^^ ERC20: Value +269 │ let token1: ERC20 = ERC20(self.token1) + │ ^^^^ UniswapV2Pair: Value note: - ┌─ uniswap.fe:269:40 + ┌─ uniswap.fe:269:35 │ -269 │ let token1: ERC20 = ERC20(ctx, self.token1) - │ ^^^^^^^^^^^ address: Storage { nonce: Some(6) } => Value +269 │ let token1: ERC20 = ERC20(self.token1) + │ ^^^^^^^^^^^ address: Storage { nonce: Some(6) } => Value note: ┌─ uniswap.fe:269:29 │ -269 │ let token1: ERC20 = ERC20(ctx, self.token1) - │ ^^^^^^^^^^^^^^^^^^^^^^^ ERC20: Value +269 │ let token1: ERC20 = ERC20(self.token1) + │ ^^^^^^^^^^^^^^^^^^ ERC20: Value 270 │ self._update(ctx, │ ^^^^ ^^^ Context: Memory │ │ @@ -4172,13 +4176,13 @@ note: │ 294 │ ╭ pub fn fee_to(self) -> address: 295 │ │ return self.fee_to - │ ╰──────────────────────────^ attributes hash: 4904320013011961635 + │ ╰──────────────────────────^ attributes hash: 14998164248694947089 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 12113..12117, + span: 12168..12172, }, ), ctx_decl: None, @@ -4207,13 +4211,13 @@ note: │ 297 │ ╭ pub fn fee_to_setter(self) -> address: 298 │ │ return self.fee_to_setter - │ ╰─────────────────────────────────^ attributes hash: 5518987369979851307 + │ ╰─────────────────────────────────^ attributes hash: 12268499969235247241 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 12184..12188, + span: 12239..12243, }, ), ctx_decl: None, @@ -4242,13 +4246,13 @@ note: │ 300 │ ╭ pub fn all_pairs_length(self) -> u256: 301 │ │ return self.pair_counter - │ ╰────────────────────────────────^ attributes hash: 15715561092694977964 + │ ╰────────────────────────────────^ attributes hash: 12450952291628893652 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: Ref, - span: 12265..12269, + span: 12320..12324, }, ), ctx_decl: None, @@ -4277,20 +4281,20 @@ note: note: ┌─ uniswap.fe:303:5 │ -303 │ ╭ pub fn create_pair(mut self, ctx: Context, _ token_a: address, _ token_b: address) -> address: +303 │ ╭ pub fn create_pair(mut self, mut ctx: Context, _ token_a: address, _ token_b: address) -> address: 304 │ │ assert token_a != token_b, "UniswapV2: IDENTICAL_ADDRESSES" 305 │ │ 306 │ │ let token0: address = token_a if token_a < token_b else token_b · │ 320 │ │ emit PairCreated(ctx, token0, token1, pair: address(pair), index: self.pair_counter) 321 │ │ return address(pair) - │ ╰────────────────────────────^ attributes hash: 5900270013228879828 + │ ╰────────────────────────────^ attributes hash: 11463342532181064177 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 12341..12345, + span: 12396..12400, }, ), ctx_decl: Some( @@ -4298,7 +4302,7 @@ note: ), params: [ FunctionParam { - is_mut: false, + is_mut: true, label: None, name: "ctx", typ: Ok( @@ -4501,17 +4505,18 @@ note: │ 312 │ let pair: UniswapV2Pair = UniswapV2Pair.create2(ctx, 0, salt) │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UniswapV2Pair: Value -313 │ pair.initialize(token0, token1) - │ ^^^^ ^^^^^^ ^^^^^^ address: Value - │ │ │ - │ │ address: Value +313 │ pair.initialize(ctx, token0, token1) + │ ^^^^ ^^^ ^^^^^^ ^^^^^^ address: Value + │ │ │ │ + │ │ │ address: Value + │ │ Context: Memory │ UniswapV2Pair: Value note: ┌─ uniswap.fe:313:9 │ -313 │ pair.initialize(token0, token1) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (): Value +313 │ pair.initialize(ctx, token0, token1) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (): Value 314 │ 315 │ self.pairs[token0][token1] = address(pair) │ ^^^^ UniswapV2Factory: Value @@ -4717,13 +4722,13 @@ note: 323 │ ╭ pub fn set_fee_to(mut self, ctx: Context, fee_to: address): 324 │ │ assert ctx.msg_sender() == self.fee_to_setter, "UniswapV2: FORBIDDEN" 325 │ │ self.fee_to = fee_to - │ ╰────────────────────────────^ attributes hash: 10388358816800266756 + │ ╰────────────────────────────^ attributes hash: 1667745660293295468 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 13309..13313, + span: 13373..13377, }, ), ctx_decl: Some( @@ -4805,13 +4810,13 @@ note: 327 │ ╭ pub fn set_fee_to_setter(mut self, ctx: Context, fee_to_setter: address): 328 │ │ assert ctx.msg_sender() == fee_to_setter, "UniswapV2: FORBIDDEN" 329 │ │ self.fee_to_setter = fee_to_setter - │ ╰──────────────────────────────────────────^ attributes hash: 2480911855679723100 + │ ╰──────────────────────────────────────────^ attributes hash: 4641784899820462275 │ = FunctionSignature { self_decl: Some( SelfDecl { kind: MutRef, - span: 13488..13492, + span: 13552..13556, }, ), ctx_decl: Some( diff --git a/crates/analyzer/tests/snapshots/errors__bad_visibility.snap b/crates/analyzer/tests/snapshots/errors__bad_visibility.snap index c908031945..028d6bc607 100644 --- a/crates/analyzer/tests/snapshots/errors__bad_visibility.snap +++ b/crates/analyzer/tests/snapshots/errors__bad_visibility.snap @@ -147,7 +147,7 @@ error: the function `my_func` is private error: the type `MyContract` is private ┌─ compile_errors/bad_visibility/src/main.fe:22:16 │ -22 │ let _: MyContract = MyContract(ctx, addr) +22 │ let _: MyContract = MyContract(addr) │ ^^^^^^^^^^ this type is not `pub` │ ┌─ compile_errors/bad_visibility/src/foo.fe:14:10 @@ -161,7 +161,7 @@ error: the type `MyContract` is private error: the type `MyContract` is private ┌─ compile_errors/bad_visibility/src/main.fe:22:29 │ -22 │ let _: MyContract = MyContract(ctx, addr) +22 │ let _: MyContract = MyContract(addr) │ ^^^^^^^^^^ this type is not `pub` │ ┌─ compile_errors/bad_visibility/src/foo.fe:14:10 diff --git a/crates/analyzer/tests/snapshots/errors__call_non_pub_fn_on_external_contract.snap b/crates/analyzer/tests/snapshots/errors__call_non_pub_fn_on_external_contract.snap index e12817b6fa..827f54b189 100644 --- a/crates/analyzer/tests/snapshots/errors__call_non_pub_fn_on_external_contract.snap +++ b/crates/analyzer/tests/snapshots/errors__call_non_pub_fn_on_external_contract.snap @@ -3,22 +3,14 @@ source: crates/analyzer/tests/errors.rs expression: "error_string(&path, test_files::fixture(path))" --- -error: cannot modify `self`, as it is not mutable - ┌─ compile_errors/call_non_pub_fn_on_external_contract.fe:6:6 - │ -5 │ fn do_private_thingz(self): - │ ---- consider changing this to be mutable: `mut self` -6 │ self.val = 100 - │ ^^^^ not mutable - error: the function `do_private_thingz` on `contract Foo` is private - ┌─ compile_errors/call_non_pub_fn_on_external_contract.fe:10:26 + ┌─ compile_errors/call_non_pub_fn_on_external_contract.fe:10:21 │ - 5 │ ╭ fn do_private_thingz(self): + 5 │ ╭ fn do_private_thingz(mut self): 6 │ │ self.val = 100 │ ╰───────────────────' `do_private_thingz` is defined here · │ -10 │ Foo(ctx, address(0)).do_private_thingz() - │ ^^^^^^^^^^^^^^^^^ this function is not `pub` +10 │ Foo(address(0)).do_private_thingz() + │ ^^^^^^^^^^^^^^^^^ this function is not `pub` diff --git a/crates/analyzer/tests/snapshots/errors__call_undefined_function_on_external_contract.snap b/crates/analyzer/tests/snapshots/errors__call_undefined_function_on_external_contract.snap index 1e1dd874b0..5365cd45d4 100644 --- a/crates/analyzer/tests/snapshots/errors__call_undefined_function_on_external_contract.snap +++ b/crates/analyzer/tests/snapshots/errors__call_undefined_function_on_external_contract.snap @@ -4,9 +4,9 @@ expression: "error_string(&path, test_files::fixture(path))" --- error: No function `doesnt_exist` exists on type `Foo` - ┌─ compile_errors/call_undefined_function_on_external_contract.fe:8:26 + ┌─ compile_errors/call_undefined_function_on_external_contract.fe:8:21 │ -8 │ Foo(ctx, address(0)).doesnt_exist() - │ ^^^^^^^^^^^^ undefined function +8 │ Foo(address(0)).doesnt_exist() + │ ^^^^^^^^^^^^ undefined function diff --git a/crates/analyzer/tests/snapshots/errors__ctx_builtins_param_incorrect_type.snap b/crates/analyzer/tests/snapshots/errors__ctx_builtins_param_incorrect_type.snap index 962225fc10..cef3b0da4b 100644 --- a/crates/analyzer/tests/snapshots/errors__ctx_builtins_param_incorrect_type.snap +++ b/crates/analyzer/tests/snapshots/errors__ctx_builtins_param_incorrect_type.snap @@ -3,30 +3,16 @@ source: crates/analyzer/tests/errors.rs expression: "error_string(&path, test_files::fixture(path))" --- -error: type mismatch - ┌─ compile_errors/ctx_builtins_param_incorrect_type.fe:12:40 - │ -12 │ let existing_barn: Barn = Barn("hello world", address(0)) - │ ^^^^^^^^^^^^^ this has type `String<11>`; expected type `Context` - error: incorrect type for argument to `Barn.create` - ┌─ compile_errors/ctx_builtins_param_incorrect_type.fe:13:46 + ┌─ compile_errors/ctx_builtins_param_incorrect_type.fe:12:46 │ -13 │ let created_barn: Barn = Barn.create(address(26), 0) +12 │ let created_barn: Barn = Barn.create(address(26), 0) │ ^^^^^^^^^^^ this has type `address`; expected `Context` -error: missing argument label - ┌─ compile_errors/ctx_builtins_param_incorrect_type.fe:14:27 - │ -14 │ emit WorldMessage(42, message: "hello world") - │ ^ add `ctx:` here - │ - = Note: this label is optional if the argument is a variable named `ctx`. - error: incorrect type for `WorldMessage` argument `ctx` - ┌─ compile_errors/ctx_builtins_param_incorrect_type.fe:14:27 + ┌─ compile_errors/ctx_builtins_param_incorrect_type.fe:13:27 │ -14 │ emit WorldMessage(42, message: "hello world") +13 │ emit WorldMessage(42, message: "hello world") │ ^^ this has type `u256`; expected type `Context` diff --git a/crates/analyzer/tests/snapshots/errors__ctx_missing_event.snap b/crates/analyzer/tests/snapshots/errors__ctx_missing_event.snap index 9edab54d21..688c7e8dd9 100644 --- a/crates/analyzer/tests/snapshots/errors__ctx_missing_event.snap +++ b/crates/analyzer/tests/snapshots/errors__ctx_missing_event.snap @@ -11,14 +11,6 @@ error: `HelloWorld` expects 2 arguments, but 1 was provided │ │ │ expects 2 arguments -error: argument label mismatch - ┌─ compile_errors/ctx_missing_event.fe:8:25 - │ -8 │ emit HelloWorld(message: "hello world") - │ ^^^^^^^ expected `ctx` - │ - = Note: arguments must be provided in order. - error: incorrect type for `HelloWorld` argument `ctx` ┌─ compile_errors/ctx_missing_event.fe:8:34 │ diff --git a/crates/analyzer/tests/snapshots/errors__ctx_missing_load.snap b/crates/analyzer/tests/snapshots/errors__ctx_missing_load.snap deleted file mode 100644 index 36b6261eb5..0000000000 --- a/crates/analyzer/tests/snapshots/errors__ctx_missing_load.snap +++ /dev/null @@ -1,20 +0,0 @@ ---- -source: crates/analyzer/tests/errors.rs -expression: "error_string(&path, test_files::fixture(path))" - ---- -error: `Foo` expects 2 arguments, but 1 was provided - ┌─ compile_errors/ctx_missing_load.fe:9:9 - │ -9 │ Foo(0) - │ ^^^ - supplied 1 argument - │ │ - │ expects 2 arguments - -error: type mismatch - ┌─ compile_errors/ctx_missing_load.fe:9:13 - │ -9 │ Foo(0) - │ ^ this has type `u256`; expected type `Context` - - diff --git a/crates/analyzer/tests/snapshots/errors__ctx_passed_external_call.snap b/crates/analyzer/tests/snapshots/errors__ctx_passed_external_call.snap deleted file mode 100644 index 6c06523aa9..0000000000 --- a/crates/analyzer/tests/snapshots/errors__ctx_passed_external_call.snap +++ /dev/null @@ -1,23 +0,0 @@ ---- -source: crates/analyzer/tests/errors.rs -expression: "error_string(&path, test_files::fixture(path))" - ---- -error: `bar` expects 0 arguments, but 1 was provided - ┌─ compile_errors/ctx_passed_external_call.fe:13:36 - │ -13 │ self.favorite_number = foo.bar(ctx) - │ ^^^ --- supplied 1 argument - │ │ - │ expects 0 arguments - -error: cannot modify `self`, as it is not mutable - ┌─ compile_errors/ctx_passed_external_call.fe:13:9 - │ -11 │ pub fn baz(self, ctx: Context): - │ ---- consider changing this to be mutable: `mut self` -12 │ let foo: Foo = Foo.create(ctx, 0) -13 │ self.favorite_number = foo.bar(ctx) - │ ^^^^ not mutable - - diff --git a/crates/analyzer/tests/snapshots/errors__ctx_pure.snap b/crates/analyzer/tests/snapshots/errors__ctx_pure.snap deleted file mode 100644 index 2d52ec142b..0000000000 --- a/crates/analyzer/tests/snapshots/errors__ctx_pure.snap +++ /dev/null @@ -1,12 +0,0 @@ ---- -source: crates/analyzer/tests/errors.rs -expression: "error_string(&path, test_files::fixture(path))" - ---- -error: `ctx` cannot be passed into pure functions - ┌─ compile_errors/ctx_pure.fe:3:12 - │ -3 │ pub fn foo(ctx: Context): - │ ^^^^^^^^^^^^ `ctx` can only be passed into contract functions - - diff --git a/crates/analyzer/tests/snapshots/errors__ctx_undefined_contract_init.snap b/crates/analyzer/tests/snapshots/errors__ctx_undefined_contract_init.snap deleted file mode 100644 index bb869f1b53..0000000000 --- a/crates/analyzer/tests/snapshots/errors__ctx_undefined_contract_init.snap +++ /dev/null @@ -1,28 +0,0 @@ ---- -source: crates/analyzer/tests/errors.rs -expression: "error_string(&path, test_files::fixture(path))" - ---- -error: `Bar` expects 2 arguments, but 1 was provided - ┌─ compile_errors/ctx_undefined_contract_init.fe:6:9 - │ -6 │ Bar(address(0)) - │ ^^^ ---------- supplied 1 argument - │ │ - │ expects 2 arguments - -error: `Context` is not defined - ┌─ compile_errors/ctx_undefined_contract_init.fe:6:12 - │ -5 │ pub fn baz(): - │ --- - │ │ - │ Note: declare `ctx` in this function signature - │ Example: `pub fn foo(ctx: Context, ...)` -6 │ Bar(address(0)) - │ ^^^^^^^^^^^^ `ctx` must be defined and passed into the contract constructor - │ - = Note: import context with `use std::context::Context` - = Example: MyContract(ctx, contract_address) - - diff --git a/crates/analyzer/tests/snapshots/errors__emit_bad_args.snap b/crates/analyzer/tests/snapshots/errors__emit_bad_args.snap index 7098b810ed..837ab75ce9 100644 --- a/crates/analyzer/tests/snapshots/errors__emit_bad_args.snap +++ b/crates/analyzer/tests/snapshots/errors__emit_bad_args.snap @@ -11,14 +11,6 @@ error: `Foo` expects 4 arguments, but 5 were provided │ │ │ expects 4 arguments -error: missing argument label - ┌─ compile_errors/emit_bad_args.fe:10:19 - │ -10 │ emit Foo(ctx, (1, 2), z: 10, y: true, x: 5) - │ ^ add `x:` here - │ - = Note: this label is optional if the argument is a variable named `x`. - error: incorrect type for `Foo` argument `x` ┌─ compile_errors/emit_bad_args.fe:10:19 │ diff --git a/crates/analyzer/tests/snapshots/errors__external_call_type_error.snap b/crates/analyzer/tests/snapshots/errors__external_call_type_error.snap index 9dcacfec6d..10e5107b62 100644 --- a/crates/analyzer/tests/snapshots/errors__external_call_type_error.snap +++ b/crates/analyzer/tests/snapshots/errors__external_call_type_error.snap @@ -4,9 +4,9 @@ expression: "error_string(&path, test_files::fixture(path))" --- error: incorrect type for `bar` argument at position 0 - ┌─ compile_errors/external_call_type_error.fe:9:34 + ┌─ compile_errors/external_call_type_error.fe:9:29 │ -9 │ Foo(ctx, address(0)).bar("hello world") - │ ^^^^^^^^^^^^^ this has type `String<11>`; expected type `u256` +9 │ Foo(address(0)).bar("hello world") + │ ^^^^^^^^^^^^^ this has type `String<11>`; expected type `u256` diff --git a/crates/analyzer/tests/snapshots/errors__external_call_wrong_number_of_params.snap b/crates/analyzer/tests/snapshots/errors__external_call_wrong_number_of_params.snap index bb99fd353a..35adf72d4b 100644 --- a/crates/analyzer/tests/snapshots/errors__external_call_wrong_number_of_params.snap +++ b/crates/analyzer/tests/snapshots/errors__external_call_wrong_number_of_params.snap @@ -4,18 +4,18 @@ expression: "error_string(&path, test_files::fixture(path))" --- error: `bar` expects 2 arguments, but 1 was provided - ┌─ compile_errors/external_call_wrong_number_of_params.fe:9:30 + ┌─ compile_errors/external_call_wrong_number_of_params.fe:9:25 │ -9 │ Foo(ctx, address(0)).bar(42) - │ ^^^ -- supplied 1 argument - │ │ - │ expects 2 arguments +9 │ Foo(address(0)).bar(42) + │ ^^^ -- supplied 1 argument + │ │ + │ expects 2 arguments error: missing argument label - ┌─ compile_errors/external_call_wrong_number_of_params.fe:9:34 + ┌─ compile_errors/external_call_wrong_number_of_params.fe:9:29 │ -9 │ Foo(ctx, address(0)).bar(42) - │ ^ add `a:` here +9 │ Foo(address(0)).bar(42) + │ ^ add `a:` here │ = Note: this label is optional if the argument is a variable named `a`. diff --git a/crates/analyzer/tests/snapshots/errors__mislabeled_call_args_external_contract_call.snap b/crates/analyzer/tests/snapshots/errors__mislabeled_call_args_external_contract_call.snap index 9b3deb4859..03ed6f0048 100644 --- a/crates/analyzer/tests/snapshots/errors__mislabeled_call_args_external_contract_call.snap +++ b/crates/analyzer/tests/snapshots/errors__mislabeled_call_args_external_contract_call.snap @@ -4,15 +4,15 @@ expression: "error_string(&path, test_files::fixture(path))" --- error: argument label mismatch - ┌─ compile_errors/mislabeled_call_args_external_contract_call.fe:11:30 + ┌─ compile_errors/mislabeled_call_args_external_contract_call.fe:11:25 │ -11 │ Foo(ctx, address(0)).baz(doesnt_exist: 1, me_neither: 4) - │ ^^^^^^^^^^^^ expected `val1` +11 │ Foo(address(0)).baz(doesnt_exist: 1, me_neither: 4) + │ ^^^^^^^^^^^^ expected `val1` error: argument label mismatch - ┌─ compile_errors/mislabeled_call_args_external_contract_call.fe:11:47 + ┌─ compile_errors/mislabeled_call_args_external_contract_call.fe:11:42 │ -11 │ Foo(ctx, address(0)).baz(doesnt_exist: 1, me_neither: 4) - │ ^^^^^^^^^^ expected `val2` +11 │ Foo(address(0)).baz(doesnt_exist: 1, me_neither: 4) + │ ^^^^^^^^^^ expected `val2` diff --git a/crates/analyzer/tests/snapshots/errors__self_mut_mismatch.snap b/crates/analyzer/tests/snapshots/errors__self_mut_mismatch.snap index 76ba46ebe0..3ee74661c3 100644 --- a/crates/analyzer/tests/snapshots/errors__self_mut_mismatch.snap +++ b/crates/analyzer/tests/snapshots/errors__self_mut_mismatch.snap @@ -23,11 +23,11 @@ error: cannot modify `self`, as it is not mutable │ ^^^^ not mutable error: cannot modify `self`, as it is not mutable - ┌─ compile_errors/self_mut_mismatch.fe:19:9 + ┌─ compile_errors/self_mut_mismatch.fe:28:9 │ -18 │ pub fn get_name(self) -> String<100>: +27 │ pub fn get_name(self) -> String<100>: │ ---- consider changing this to be mutable: `mut self` -19 │ self.name = "shouldnt work" +28 │ self.name = "shouldnt work" │ ^^^^ not mutable diff --git a/crates/analyzer/tests/snapshots/errors__sneaky_mutation.snap b/crates/analyzer/tests/snapshots/errors__sneaky_mutation.snap new file mode 100644 index 0000000000..a30b1c1f57 --- /dev/null +++ b/crates/analyzer/tests/snapshots/errors__sneaky_mutation.snap @@ -0,0 +1,36 @@ +--- +source: crates/analyzer/tests/errors.rs +expression: "error_string(&path, test_files::fixture(path))" + +--- +error: sneaky mutation + ┌─ compile_errors/sneaky_mutation.fe:12:5 + │ +12 │ y1 = x + │ ^^ - this is immutable + │ │ + │ this is mutable + +error: sneaky mutation + ┌─ compile_errors/sneaky_mutation.fe:26:5 + │ +26 │ w1.array = imm + │ ^^^^^^^^ --- this is immutable + │ │ + │ this is mutable + +error: expected mut arg + ┌─ compile_errors/sneaky_mutation.fe:33:19 + │ +33 │ w2.set_array2(imm) + │ ^^^ this is not mutable + +error: sneaky mutation + ┌─ compile_errors/sneaky_mutation.fe:42:9 + │ +42 │ self.array = array + │ ^^^^^^^^^^ ----- this is immutable + │ │ + │ this is mutable + + diff --git a/crates/test-files/fixtures/compile_errors/bad_visibility/src/main.fe b/crates/test-files/fixtures/compile_errors/bad_visibility/src/main.fe index fe3700989c..5b17de77c7 100644 --- a/crates/test-files/fixtures/compile_errors/bad_visibility/src/main.fe +++ b/crates/test-files/fixtures/compile_errors/bad_visibility/src/main.fe @@ -5,19 +5,19 @@ contract Main: pub fn priv_type_alias() -> MyInt: let x: MyInt = 1 return x - + pub fn priv_const() -> i32: return MY_CONST - + pub fn priv_event(): emit MyEvent(ctx, x: 1) - + pub fn priv_struct(): let s: MyStruct = MyStruct(x: 1) - + pub fn priv_func(): my_func() - + pub fn priv_contract(ctx: Context, addr: address): - let _: MyContract = MyContract(ctx, addr) + let _: MyContract = MyContract(addr) MyContract.create(ctx, 1) diff --git a/crates/test-files/fixtures/compile_errors/call_call_on_external_contract.fe b/crates/test-files/fixtures/compile_errors/call_call_on_external_contract.fe index fa77408611..c2c39197ab 100644 --- a/crates/test-files/fixtures/compile_errors/call_call_on_external_contract.fe +++ b/crates/test-files/fixtures/compile_errors/call_call_on_external_contract.fe @@ -1,4 +1,4 @@ -use std::context::Context + contract Foo: pub fn __call__(): @@ -8,6 +8,6 @@ contract Foo: contract Bar: - fn b(ctx: Context): - let foo: Foo = Foo(ctx, address(0)) + fn b(): + let foo: Foo = Foo(address(0)) foo.__call__() diff --git a/crates/test-files/fixtures/compile_errors/call_event_with_wrong_types.fe b/crates/test-files/fixtures/compile_errors/call_event_with_wrong_types.fe index acd1c26f3c..3a7e2861b9 100644 --- a/crates/test-files/fixtures/compile_errors/call_event_with_wrong_types.fe +++ b/crates/test-files/fixtures/compile_errors/call_event_with_wrong_types.fe @@ -5,5 +5,5 @@ contract Foo: val_1: String<5> idx val_2: u8 - pub fn foo(ctx: Context): + pub fn foo(mut ctx: Context): emit MyEvent(ctx, val_1: "foo bar", val_2: 1000) diff --git a/crates/test-files/fixtures/compile_errors/call_non_pub_fn_on_external_contract.fe b/crates/test-files/fixtures/compile_errors/call_non_pub_fn_on_external_contract.fe index e08c02f3d3..e9127f71b7 100644 --- a/crates/test-files/fixtures/compile_errors/call_non_pub_fn_on_external_contract.fe +++ b/crates/test-files/fixtures/compile_errors/call_non_pub_fn_on_external_contract.fe @@ -1,10 +1,10 @@ -use std::context::Context + contract Foo: val: u8 - fn do_private_thingz(self): + fn do_private_thingz(mut self): self.val = 100 contract Bar: - fn test(ctx: Context): - Foo(ctx, address(0)).do_private_thingz() + fn test(): + Foo(address(0)).do_private_thingz() diff --git a/crates/test-files/fixtures/compile_errors/call_undefined_function_on_external_contract.fe b/crates/test-files/fixtures/compile_errors/call_undefined_function_on_external_contract.fe index 422a042cfe..8ce40ba8d4 100644 --- a/crates/test-files/fixtures/compile_errors/call_undefined_function_on_external_contract.fe +++ b/crates/test-files/fixtures/compile_errors/call_undefined_function_on_external_contract.fe @@ -1,8 +1,8 @@ -use std::context::Context + contract Foo: val: u8 contract Bar: - pub fn test(ctx: Context): - Foo(ctx, address(0)).doesnt_exist() \ No newline at end of file + pub fn test(): + Foo(address(0)).doesnt_exist() \ No newline at end of file diff --git a/crates/test-files/fixtures/compile_errors/ctx_builtins_param_incorrect_type.fe b/crates/test-files/fixtures/compile_errors/ctx_builtins_param_incorrect_type.fe index 68e74c4b42..3290276c1b 100644 --- a/crates/test-files/fixtures/compile_errors/ctx_builtins_param_incorrect_type.fe +++ b/crates/test-files/fixtures/compile_errors/ctx_builtins_param_incorrect_type.fe @@ -9,6 +9,5 @@ contract Barn: contract Foo: pub fn bar(ctx: Context): - let existing_barn: Barn = Barn("hello world", address(0)) let created_barn: Barn = Barn.create(address(26), 0) emit WorldMessage(42, message: "hello world") diff --git a/crates/test-files/fixtures/compile_errors/ctx_missing_load.fe b/crates/test-files/fixtures/compile_errors/ctx_missing_load.fe deleted file mode 100644 index 56ce0bf838..0000000000 --- a/crates/test-files/fixtures/compile_errors/ctx_missing_load.fe +++ /dev/null @@ -1,9 +0,0 @@ -use std::context::Context - -contract Foo: - pub fn bar(): - pass - -contract Bar: - pub fn create_foo(ctx: Context): - Foo(0) diff --git a/crates/test-files/fixtures/compile_errors/ctx_passed_external_call.fe b/crates/test-files/fixtures/compile_errors/ctx_passed_external_call.fe deleted file mode 100644 index 3f4db78ca8..0000000000 --- a/crates/test-files/fixtures/compile_errors/ctx_passed_external_call.fe +++ /dev/null @@ -1,13 +0,0 @@ -use std::context::Context - -contract Foo: - - pub fn bar(ctx: Context) -> u256: - return ctx.block_number() - -contract Bing: - favorite_number: u256 - - pub fn baz(self, ctx: Context): - let foo: Foo = Foo.create(ctx, 0) - self.favorite_number = foo.bar(ctx) \ No newline at end of file diff --git a/crates/test-files/fixtures/compile_errors/ctx_pure.fe b/crates/test-files/fixtures/compile_errors/ctx_pure.fe deleted file mode 100644 index 1adf683fd2..0000000000 --- a/crates/test-files/fixtures/compile_errors/ctx_pure.fe +++ /dev/null @@ -1,4 +0,0 @@ -use std::context::Context - -pub fn foo(ctx: Context): - pass \ No newline at end of file diff --git a/crates/test-files/fixtures/compile_errors/ctx_undefined_contract_init.fe b/crates/test-files/fixtures/compile_errors/ctx_undefined_contract_init.fe deleted file mode 100644 index 399fc360f0..0000000000 --- a/crates/test-files/fixtures/compile_errors/ctx_undefined_contract_init.fe +++ /dev/null @@ -1,6 +0,0 @@ -contract Bar: - pass - -contract Foo: - pub fn baz(): - Bar(address(0)) \ No newline at end of file diff --git a/crates/test-files/fixtures/compile_errors/emit_bad_args.fe b/crates/test-files/fixtures/compile_errors/emit_bad_args.fe index 20a57fe12e..0ed3a75677 100644 --- a/crates/test-files/fixtures/compile_errors/emit_bad_args.fe +++ b/crates/test-files/fixtures/compile_errors/emit_bad_args.fe @@ -6,5 +6,5 @@ contract Bar: y: u256 z: bool - pub fn test(ctx: Context): + pub fn test(mut ctx: Context): emit Foo(ctx, (1, 2), z: 10, y: true, x: 5) \ No newline at end of file diff --git a/crates/test-files/fixtures/compile_errors/external_call_type_error.fe b/crates/test-files/fixtures/compile_errors/external_call_type_error.fe index 4c71c4a6be..3c12d71b39 100644 --- a/crates/test-files/fixtures/compile_errors/external_call_type_error.fe +++ b/crates/test-files/fixtures/compile_errors/external_call_type_error.fe @@ -5,5 +5,5 @@ contract Foo: pass contract FooProxy: - pub fn baz(ctx: Context): - Foo(ctx, address(0)).bar("hello world") \ No newline at end of file + pub fn baz(): + Foo(address(0)).bar("hello world") \ No newline at end of file diff --git a/crates/test-files/fixtures/compile_errors/external_call_wrong_number_of_params.fe b/crates/test-files/fixtures/compile_errors/external_call_wrong_number_of_params.fe index a7958c29d9..3bda4cdbf1 100644 --- a/crates/test-files/fixtures/compile_errors/external_call_wrong_number_of_params.fe +++ b/crates/test-files/fixtures/compile_errors/external_call_wrong_number_of_params.fe @@ -6,4 +6,4 @@ contract Foo: contract FooProxy: pub fn baz(ctx: Context): - Foo(ctx, address(0)).bar(42) + Foo(address(0)).bar(42) diff --git a/crates/test-files/fixtures/compile_errors/init_call_on_external_contract.fe b/crates/test-files/fixtures/compile_errors/init_call_on_external_contract.fe index 9c71f10a32..7248e33118 100644 --- a/crates/test-files/fixtures/compile_errors/init_call_on_external_contract.fe +++ b/crates/test-files/fixtures/compile_errors/init_call_on_external_contract.fe @@ -8,7 +8,7 @@ contract Foo: contract Bar: - fn b(ctx: Context): - let foo: Foo = Foo(ctx, address(0)) + fn b(): + let foo: Foo = Foo(address(0)) foo.f() foo.__init__() diff --git a/crates/test-files/fixtures/compile_errors/mislabeled_call_args_external_contract_call.fe b/crates/test-files/fixtures/compile_errors/mislabeled_call_args_external_contract_call.fe index 5609b68d5f..c92ca4f6c9 100644 --- a/crates/test-files/fixtures/compile_errors/mislabeled_call_args_external_contract_call.fe +++ b/crates/test-files/fixtures/compile_errors/mislabeled_call_args_external_contract_call.fe @@ -7,5 +7,5 @@ contract Foo: pass contract Bar: - pub fn test(ctx: Context): - Foo(ctx, address(0)).baz(doesnt_exist: 1, me_neither: 4) \ No newline at end of file + pub fn test(): + Foo(address(0)).baz(doesnt_exist: 1, me_neither: 4) \ No newline at end of file diff --git a/crates/test-files/fixtures/compile_errors/self_mut_mismatch.fe b/crates/test-files/fixtures/compile_errors/self_mut_mismatch.fe index 971209bdcb..a4cfad179e 100644 --- a/crates/test-files/fixtures/compile_errors/self_mut_mismatch.fe +++ b/crates/test-files/fixtures/compile_errors/self_mut_mismatch.fe @@ -12,6 +12,15 @@ contract Foo: let m: Person = Person(name: "Martha") m.set_name("May") + fn test_contract(): + let b: Beef = Beef(address(0xbeef)) + +contract Beef: + y: u8 + + pub fn set_y(mut self, y: u8): + self.y = y + struct Person: pub name: String<100> @@ -19,5 +28,5 @@ struct Person: self.name = "shouldnt work" return self.name - pub fn set_name(mut self, _ name: String<100>): - self.name = name \ No newline at end of file + pub fn set_name(mut self, mut _ name: String<100>): + self.name = name diff --git a/crates/test-files/fixtures/compile_errors/sneaky_mutation.fe b/crates/test-files/fixtures/compile_errors/sneaky_mutation.fe index d87a4a9288..3310e85792 100644 --- a/crates/test-files/fixtures/compile_errors/sneaky_mutation.fe +++ b/crates/test-files/fixtures/compile_errors/sneaky_mutation.fe @@ -1,5 +1,47 @@ fn f(): - let x: Array = [1, 2, 3] - let mut y: Array = x - y[0] = 10 + # Mutate an immutable via aliasing... + + # ...at constuction time + let x: Array = [1, 2, 3] + let mut y0: Array = x # XXX error + y0[0] = 10 + + # ...in an assignment + let mut y1: Array + y1 = x + y1[0] = 20 + + +fn g(): + # Put an immutable array into a mutable struct... + + # ...at construction time + let imm: Array = [5, 5, 5] + let mut w0: ArrayWrapper = ArrayWrapper(array: imm) # XXX error + w0.array[0] = 100 + + # ...by setting a field + let mut w1: ArrayWrapper = ArrayWrapper(array: [1, 2, 3]) + w1.array = imm + w1.array[1] = 100 + + # ...via a fn call that takes non-mut + let mut w2: ArrayWrapper = ArrayWrapper(array: [1, 2, 3]) + w2.set_array(imm) + # ...via a fn call that takes mut + w2.set_array2(imm) + + # This should work. + w2.set_array2([10, 10, 10]) + +struct ArrayWrapper: + pub array: Array + + pub fn set_array(mut self, _ array: Array): + self.array = array + self.array[2] = 100 + + pub fn set_array2(mut self, mut _ array: Array): + self.array = array + self.array[2] = 100 diff --git a/crates/test-files/fixtures/demos/erc20_token.fe b/crates/test-files/fixtures/demos/erc20_token.fe index 63bbe8f6ff..9e1bdd51b6 100644 --- a/crates/test-files/fixtures/demos/erc20_token.fe +++ b/crates/test-files/fixtures/demos/erc20_token.fe @@ -18,7 +18,7 @@ contract ERC20: idx to: address value: u256 - pub fn __init__(mut self, ctx: Context, name: String<100>, symbol: String<100>): + pub fn __init__(mut self, mut ctx: Context, name: String<100>, symbol: String<100>): self._name = name self._symbol = symbol self._decimals = u8(18) @@ -39,32 +39,32 @@ contract ERC20: pub fn balanceOf(self, _ account: address) -> u256: return self._balances[account] - pub fn transfer(mut self, ctx: Context, recipient: address, value: u256) -> bool: + pub fn transfer(mut self, mut ctx: Context, recipient: address, value: u256) -> bool: self._transfer(ctx, sender: ctx.msg_sender(), recipient, value) return true pub fn allowance(self, owner: address, spender: address) -> u256: return self._allowances[owner][spender] - pub fn approve(mut self, ctx: Context, spender: address, value: u256) -> bool: + pub fn approve(mut self, mut ctx: Context, spender: address, value: u256) -> bool: self._approve(ctx, owner: ctx.msg_sender(), spender, value) return true - pub fn transferFrom(mut self, ctx: Context, sender: address, recipient: address, value: u256) -> bool: + pub fn transferFrom(mut self, mut ctx: Context, sender: address, recipient: address, value: u256) -> bool: assert self._allowances[sender][ctx.msg_sender()] >= value self._transfer(ctx, sender, recipient, value) self._approve(ctx, owner: sender, spender: ctx.msg_sender(), value: self._allowances[sender][ctx.msg_sender()] - value) return true - pub fn increaseAllowance(mut self, ctx: Context, spender: address, addedValue: u256) -> bool: + pub fn increaseAllowance(mut self, mut ctx: Context, spender: address, addedValue: u256) -> bool: self._approve(ctx, owner: ctx.msg_sender(), spender, value: self._allowances[ctx.msg_sender()][spender] + addedValue) return true - pub fn decreaseAllowance(mut self, ctx: Context, spender: address, subtractedValue: u256) -> bool: + pub fn decreaseAllowance(mut self, mut ctx: Context, spender: address, subtractedValue: u256) -> bool: self._approve(ctx, owner: ctx.msg_sender(), spender, value: self._allowances[ctx.msg_sender()][spender] - subtractedValue) return true - fn _transfer(mut self, ctx: Context, sender: address, recipient: address, value: u256): + fn _transfer(mut self, mut ctx: Context, sender: address, recipient: address, value: u256): assert sender != address(0) assert recipient != address(0) _before_token_transfer(from: sender, to: recipient, value) @@ -72,21 +72,21 @@ contract ERC20: self._balances[recipient] = self._balances[recipient] + value emit Transfer(ctx, from: sender, to: recipient, value) - fn _mint(mut self, ctx: Context, account: address, value: u256): + fn _mint(mut self, mut ctx: Context, account: address, value: u256): assert account != address(0) _before_token_transfer(from: address(0), to: account, value) self._total_supply = self._total_supply + value self._balances[account] = self._balances[account] + value emit Transfer(ctx, from: address(0), to: account, value) - fn _burn(mut self, ctx: Context, account: address, value: u256): + fn _burn(mut self, mut ctx: Context, account: address, value: u256): assert account != address(0) _before_token_transfer(from: account, to: address(0), value) self._balances[account] = self._balances[account] - value self._total_supply = self._total_supply - value emit Transfer(ctx, from: account, to: address(0), value) - fn _approve(mut self, ctx: Context, owner: address, spender: address, value: u256): + fn _approve(mut self, mut ctx: Context, owner: address, spender: address, value: u256): assert owner != address(0) assert spender != address(0) self._allowances[owner][spender] = value diff --git a/crates/test-files/fixtures/demos/guest_book.fe b/crates/test-files/fixtures/demos/guest_book.fe index 1ccd954956..410e4dea84 100644 --- a/crates/test-files/fixtures/demos/guest_book.fe +++ b/crates/test-files/fixtures/demos/guest_book.fe @@ -10,7 +10,7 @@ contract GuestBook: event Signed: book_msg: String<100> - pub fn sign(mut self, ctx: Context, book_msg: String<100>): + pub fn sign(mut self, mut ctx: Context, book_msg: String<100>): # All storage access is explicit using `self.` self.messages[ctx.msg_sender()] = book_msg diff --git a/crates/test-files/fixtures/demos/uniswap.fe b/crates/test-files/fixtures/demos/uniswap.fe index 2d47050db2..634cb47d5b 100644 --- a/crates/test-files/fixtures/demos/uniswap.fe +++ b/crates/test-files/fixtures/demos/uniswap.fe @@ -1,10 +1,10 @@ use std::context::Context contract ERC20: - pub fn balanceOf(_ account: address) -> u256: + pub fn balanceOf(self, _ account: address) -> u256: return 0 - pub fn transfer(to: address, _ amount: u256) -> bool: + pub fn transfer(mut ctx: Context, to: address, _ amount: u256) -> bool: return false contract UniswapV2Pair: @@ -74,36 +74,36 @@ contract UniswapV2Pair: pub fn token1(self) -> address: return self.token1 - fn _mint(mut self, ctx: Context, to: address, value: u256): + fn _mint(mut self, mut ctx: Context, to: address, value: u256): self.total_supply = self.total_supply + value self.balances[to] = self.balances[to] + value emit Transfer(ctx, from: address(0), to, value) - fn _burn(mut self, ctx: Context, from: address, value: u256): + fn _burn(mut self, mut ctx: Context, from: address, value: u256): self.balances[from] = self.balances[from] - value self.total_supply = self.total_supply - value emit Transfer(ctx, from, to: address(0), value) - fn _approve(mut self, ctx: Context, owner: address, spender: address, value: u256): + fn _approve(mut self, mut ctx: Context, owner: address, spender: address, value: u256): self.allowances[owner][spender] = value emit Approval(ctx, owner, spender, value) - fn _transfer(mut self, ctx: Context, from: address, to: address, value: u256): + fn _transfer(mut self, mut ctx: Context, from: address, to: address, value: u256): self.balances[from] = self.balances[from] - value self.balances[to] = self.balances[to] + value emit Transfer(ctx, from, to, value) - pub fn approve(mut self, ctx: Context, spender: address, value: u256) -> bool: + pub fn approve(mut self, mut ctx: Context, spender: address, value: u256) -> bool: self._approve(ctx, owner: ctx.msg_sender(), spender, value) return true - pub fn transfer(mut self, ctx: Context, to: address, value: u256) -> bool: + pub fn transfer(mut self, mut ctx: Context, to: address, value: u256) -> bool: self._transfer(ctx, from: ctx.msg_sender(), to, value) return true - pub fn transferFrom(mut self, ctx: Context, from: address, to: address, value: u256) -> bool: + pub fn transferFrom(mut self, mut ctx: Context, from: address, to: address, value: u256) -> bool: assert self.allowances[from][ctx.msg_sender()] >= value self.allowances[from][ctx.msg_sender()] = self.allowances[from][ctx.msg_sender()] - value self._transfer(ctx, from, to, value) @@ -122,7 +122,7 @@ contract UniswapV2Pair: self.token1 = token1 # update reserves and, on the first call per block, price accumulators - fn _update(mut self, ctx: Context, balance0: u256, balance1: u256, reserve0: u256, reserve1: u256): + fn _update(mut self, mut ctx: Context, balance0: u256, balance1: u256, reserve0: u256, reserve1: u256): # changed from u32s let block_timestamp: u256 = ctx.block_timestamp() % 2**32 # TODO: reproduce desired overflow (https://github.com/ethereum/fe/issues/286) @@ -138,8 +138,8 @@ contract UniswapV2Pair: emit Sync(ctx, reserve0: self.reserve0, reserve1: self.reserve1) # if fee is on, mint liquidity equivalent to 1/6th of the growth in sqrt(k) - fn _mint_fee(mut self, ctx: Context, reserve0: u256, reserve1: u256) -> bool: - let fee_to: address = UniswapV2Factory(ctx, self.factory).fee_to() + fn _mint_fee(mut self, mut ctx: Context, reserve0: u256, reserve1: u256) -> bool: + let fee_to: address = UniswapV2Factory(self.factory).fee_to() let fee_on: bool = fee_to != address(0) let k_last: u256 = self.k_last # gas savings if fee_on: @@ -158,12 +158,12 @@ contract UniswapV2Pair: return fee_on # this low-level function should be called from a contract which performs important safety checks - pub fn mint(mut self, ctx: Context, to: address) -> u256: + pub fn mint(mut self, mut ctx: Context, to: address) -> u256: let MINIMUM_LIQUIDITY: u256 = 1000 let reserve0: u256 = self.reserve0 let reserve1: u256 = self.reserve1 - let balance0: u256 = ERC20(ctx, self.token0).balanceOf(ctx.self_address()) - let balance1: u256 = ERC20(ctx, self.token1).balanceOf(ctx.self_address()) + let balance0: u256 = ERC20(self.token0).balanceOf(ctx.self_address()) + let balance1: u256 = ERC20(self.token1).balanceOf(ctx.self_address()) let amount0: u256 = balance0 - self.reserve0 let amount1: u256 = balance1 - self.reserve1 @@ -188,11 +188,11 @@ contract UniswapV2Pair: return liquidity # this low-level function should be called from a contract which performs important safety checks - pub fn burn(mut self, ctx: Context, to: address) -> (u256, u256): + pub fn burn(mut self, mut ctx: Context, to: address) -> (u256, u256): let reserve0: u256 = self.reserve0 let reserve1: u256 = self.reserve1 - let token0: ERC20 = ERC20(ctx, self.token0) - let token1: ERC20 = ERC20(ctx, self.token1) + let token0: ERC20 = ERC20(self.token0) + let token1: ERC20 = ERC20(self.token1) let mut balance0: u256 = token0.balanceOf(ctx.self_address()) let mut balance1: u256 = token1.balanceOf(ctx.self_address()) let liquidity: u256 = self.balances[ctx.self_address()] @@ -203,8 +203,8 @@ contract UniswapV2Pair: let amount1: u256 = (liquidity * balance1) / total_supply # using balances ensures pro-rata distribution assert amount0 > 0 and amount1 > 0, "UniswapV2: INSUFFICIENT_LIQUIDITY_BURNED" self._burn(ctx, from: ctx.self_address(), value: liquidity) - token0.transfer(to, amount0) - token1.transfer(to, amount1) + token0.transfer(ctx, to, amount0) + token1.transfer(ctx, to, amount1) balance0 = token0.balanceOf(ctx.self_address()) balance1 = token1.balanceOf(ctx.self_address()) @@ -219,22 +219,22 @@ contract UniswapV2Pair: # this low-level function should be called from a contract which performs important safety checks # TODO: add support for the bytes type (https://github.com/ethereum/fe/issues/280) # pub fn swap(amount0_out: u256, amount1_out: u256, to: address, data: bytes): - pub fn swap(mut self, ctx: Context, amount0_out: u256, amount1_out: u256, to: address): + pub fn swap(mut self, mut ctx: Context, amount0_out: u256, amount1_out: u256, to: address): assert amount0_out > 0 or amount1_out > 0, "UniswapV2: INSUFFICIENT_OUTPUT_AMOUNT" let reserve0: u256 = self.reserve0 let reserve1: u256 = self.reserve1 assert amount0_out < reserve0 and amount1_out < reserve1, "UniswapV2: INSUFFICIENT_LIQUIDITY" - let token0: ERC20 = ERC20(ctx, self.token0) - let token1: ERC20 = ERC20(ctx, self.token1) + let token0: ERC20 = ERC20(self.token0) + let token1: ERC20 = ERC20(self.token1) # TODO: we should be using `token0.address` (https://github.com/ethereum/fe/issues/287) assert to != address(token0) and to != address(token1), "UniswapV2: INVALID_TO" if amount0_out > 0: - token0.transfer(to, amount0_out) # optimistically transfer tokens + token0.transfer(ctx, to, amount0_out) # optimistically transfer tokens if amount1_out > 0: - token1.transfer(to, amount1_out) # optimistically transfer tokens + token1.transfer(ctx, to, amount1_out) # optimistically transfer tokens # TODO: bytes support # if data.length > 0: # IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0_out, amount1_out, data) @@ -256,17 +256,17 @@ contract UniswapV2Pair: emit Swap(ctx, sender: ctx.msg_sender(), amount0_in, amount1_in, amount0_out, amount1_out, to) # force balances to match reserves - pub fn skim(mut self, ctx: Context, to: address): - let token0: ERC20 = ERC20(ctx, self.token0) # gas savings - let token1: ERC20 = ERC20(ctx, self.token1) # gas savings + pub fn skim(mut self, mut ctx: Context, to: address): + let token0: ERC20 = ERC20(self.token0) # gas savings + let token1: ERC20 = ERC20(self.token1) # gas savings - token0.transfer(to, token0.balanceOf(ctx.self_address()) - self.reserve0) - token1.transfer(to, token1.balanceOf(ctx.self_address()) - self.reserve1) + token0.transfer(ctx, to, token0.balanceOf(ctx.self_address()) - self.reserve0) + token1.transfer(ctx, to, token1.balanceOf(ctx.self_address()) - self.reserve1) # force reserves to match balances - pub fn sync(mut self, ctx: Context): - let token0: ERC20 = ERC20(ctx, self.token0) - let token1: ERC20 = ERC20(ctx, self.token1) + pub fn sync(mut self, mut ctx: Context): + let token0: ERC20 = ERC20(self.token0) + let token1: ERC20 = ERC20(self.token1) self._update(ctx, balance0: token0.balanceOf(ctx.self_address()), balance1: token1.balanceOf(ctx.self_address()), @@ -300,7 +300,7 @@ contract UniswapV2Factory: pub fn all_pairs_length(self) -> u256: return self.pair_counter - pub fn create_pair(mut self, ctx: Context, _ token_a: address, _ token_b: address) -> address: + pub fn create_pair(mut self, mut ctx: Context, _ token_a: address, _ token_b: address) -> address: assert token_a != token_b, "UniswapV2: IDENTICAL_ADDRESSES" let token0: address = token_a if token_a < token_b else token_b @@ -310,7 +310,7 @@ contract UniswapV2Factory: let salt: u256 = keccak256((token0, token1).abi_encode()) let pair: UniswapV2Pair = UniswapV2Pair.create2(ctx, 0, salt) - pair.initialize(token0, token1) + pair.initialize(ctx, token0, token1) self.pairs[token0][token1] = address(pair) self.pairs[token1][token0] = address(pair) diff --git a/crates/test-files/fixtures/features/events.fe b/crates/test-files/fixtures/features/events.fe index 503330aff9..8aca1e191a 100644 --- a/crates/test-files/fixtures/features/events.fe +++ b/crates/test-files/fixtures/features/events.fe @@ -18,16 +18,16 @@ contract Foo: event Addresses: addrs: Array - pub fn emit_nums(ctx: Context): + pub fn emit_nums(mut ctx: Context): emit Nums(ctx, num1: 26, num2: 42) - pub fn emit_bases(ctx: Context, addr: address): + pub fn emit_bases(mut ctx: Context, addr: address): emit Bases(ctx, num: 26, addr) - pub fn emit_mix(ctx: Context, addr: address, my_bytes: Array): + pub fn emit_mix(mut ctx: Context, addr: address, my_bytes: Array): emit Mix(ctx, num1: 26, addr, num2: 42, my_bytes) - pub fn emit_addresses(ctx: Context, addr1: address, addr2: address): + pub fn emit_addresses(mut ctx: Context, addr1: address, addr2: address): let mut addrs: Array addrs[0] = addr1 addrs[1] = addr2 diff --git a/crates/test-files/fixtures/features/external_contract.fe b/crates/test-files/fixtures/features/external_contract.fe index 328e6fa43d..9780f67817 100644 --- a/crates/test-files/fixtures/features/external_contract.fe +++ b/crates/test-files/fixtures/features/external_contract.fe @@ -1,13 +1,26 @@ use std::context::Context +event MyEvent: + num: u256 + addrs: Array + str: String<11> + +fn emit_MyEvent(mut ctx: Context, _ num: u256, _ addrs: Array, _ str: String<11>): + emit MyEvent(ctx, num, addrs, str) + + contract Foo: - event MyEvent: - my_num: u256 - my_addrs: Array - my_string: String<11> + my_num: u256 + my_addrs: Array + my_string: String<11> + + pub fn set_stuff(mut self, my_num: u256, my_addrs: Array, my_string: String<11>): + self.my_num = my_num + self.my_addrs = my_addrs + self.my_string = my_string - pub fn emit_event(ctx: Context, my_num: u256, my_addrs: Array, my_string: String<11>): - emit MyEvent(ctx, my_num, my_addrs, my_string) + pub fn emit_event(self, mut ctx: Context): + emit_MyEvent(ctx, self.my_num, self.my_addrs.to_mem(), self.my_string.to_mem()) pub fn build_array(a: u256, b: u256) -> Array: let mut my_array: Array @@ -18,20 +31,21 @@ contract Foo: contract FooProxy: pub fn call_emit_event( - ctx: Context, + mut ctx: Context, foo_address: address, my_num: u256, my_addrs: Array, my_string: String<11> ): - let foo: Foo = Foo(ctx, foo_address) - foo.emit_event(my_num, my_addrs, my_string) + let foo: Foo = Foo(foo_address) + foo.set_stuff(my_num, my_addrs, my_string) + foo.emit_event(ctx) pub fn call_build_array( - ctx: Context, + mut ctx: Context, foo_address: address, a: u256, b: u256, ) -> Array: - let foo: Foo = Foo(ctx, foo_address) + let foo: Foo = Foo(foo_address) return foo.build_array(a, b) diff --git a/crates/test-files/fixtures/features/module_level_events.fe b/crates/test-files/fixtures/features/module_level_events.fe index a718d00070..16dc203056 100644 --- a/crates/test-files/fixtures/features/module_level_events.fe +++ b/crates/test-files/fixtures/features/module_level_events.fe @@ -6,5 +6,5 @@ event Transfer: value: u256 contract Foo: - fn transfer(ctx: Context, to : address, value : u256): + fn transfer(mut ctx: Context, to: address, value: u256): emit Transfer(ctx, sender: ctx.msg_sender(), receiver: to, value) \ No newline at end of file diff --git a/crates/test-files/fixtures/features/ownable.fe b/crates/test-files/fixtures/features/ownable.fe index cb034ef10f..a340be808a 100644 --- a/crates/test-files/fixtures/features/ownable.fe +++ b/crates/test-files/fixtures/features/ownable.fe @@ -13,12 +13,12 @@ contract Ownable: pub fn owner(self) -> address: return self._owner - pub fn renounceOwnership(mut self, ctx: Context): + pub fn renounceOwnership(mut self, mut ctx: Context): assert ctx.msg_sender() == self._owner self._owner = address(0) emit OwnershipTransferred(ctx, previousOwner: ctx.msg_sender(), newOwner: address(0)) - pub fn transferOwnership(mut self, ctx: Context, newOwner: address): + pub fn transferOwnership(mut self, mut ctx: Context, newOwner: address): assert ctx.msg_sender() == self._owner assert newOwner != address(0) self._owner = newOwner diff --git a/crates/test-files/fixtures/features/sized_vals_in_sto.fe b/crates/test-files/fixtures/features/sized_vals_in_sto.fe index 88ca3e538e..0180e7b72c 100644 --- a/crates/test-files/fixtures/features/sized_vals_in_sto.fe +++ b/crates/test-files/fixtures/features/sized_vals_in_sto.fe @@ -28,7 +28,7 @@ contract Foo: pub fn read_str(self) -> String<26>: return self.str.to_mem() - pub fn emit_event(self, ctx: Context): + pub fn emit_event(self, mut ctx: Context): emit MyEvent( ctx, num: self.num, diff --git a/crates/test-files/fixtures/features/strings.fe b/crates/test-files/fixtures/features/strings.fe index e4bf4e4d44..fa88f419c4 100644 --- a/crates/test-files/fixtures/features/strings.fe +++ b/crates/test-files/fixtures/features/strings.fe @@ -10,7 +10,7 @@ contract Foo: s4: String<18> s5: String<100> - pub fn __init__(ctx: Context, s1: String<42>, a: address, s2: String<26>, u: u256, s3: String<100>): + pub fn __init__(mut ctx: Context, s1: String<42>, a: address, s2: String<26>, u: u256, s3: String<100>): emit MyEvent(ctx, s2, u, s1, s3, a, s4: "static string", s5: String<100>("foo")) pub fn bar(s1: String<100>, s2: String<100>) -> String<100>: @@ -28,5 +28,3 @@ contract Foo: pub fn return_special_chars() -> String<18>: return "\n\"'\r\t foo\\" - - diff --git a/crates/test-files/fixtures/features/two_contracts.fe b/crates/test-files/fixtures/features/two_contracts.fe index a3c854c5ff..4dcdbc556e 100644 --- a/crates/test-files/fixtures/features/two_contracts.fe +++ b/crates/test-files/fixtures/features/two_contracts.fe @@ -16,8 +16,8 @@ contract Foo: contract Bar: other: Foo - pub fn set_foo_addr(mut self, ctx: Context, _ addr: address): - self.other = Foo(ctx, addr) + pub fn set_foo_addr(mut self, _ addr: address): + self.other = Foo(addr) pub fn answer(self) -> u256: return self.other.add(20, 22) diff --git a/crates/test-files/fixtures/stress/abi_encoding_stress.fe b/crates/test-files/fixtures/stress/abi_encoding_stress.fe index c592bd4102..98aceafe88 100644 --- a/crates/test-files/fixtures/stress/abi_encoding_stress.fe +++ b/crates/test-files/fixtures/stress/abi_encoding_stress.fe @@ -73,7 +73,7 @@ contract Foo: my_struct.my_addr = address(9999) return my_struct - pub fn emit_my_event(self, ctx: Context): + pub fn emit_my_event(self, mut ctx: Context): emit MyEvent( ctx, my_addrs: self.my_addrs.to_mem(), diff --git a/crates/test-files/fixtures/stress/data_copying_stress.fe b/crates/test-files/fixtures/stress/data_copying_stress.fe index c17f851784..0e21afe729 100644 --- a/crates/test-files/fixtures/stress/data_copying_stress.fe +++ b/crates/test-files/fixtures/stress/data_copying_stress.fe @@ -67,14 +67,14 @@ contract Foo: my_nums_mem = self.my_nums.to_mem() return my_nums_mem - pub fn emit_my_event(self, ctx: Context): + pub fn emit_my_event(self, mut ctx: Context): emit_my_event_internal( ctx, self.my_string.to_mem(), self.my_u256.to_mem() ) - fn emit_my_event_internal(ctx: Context, _ my_string: String<42>, _ my_u256: u256): + fn emit_my_event_internal(mut ctx: Context, _ my_string: String<42>, _ my_u256: u256): emit MyEvent(ctx, my_string, my_u256) pub fn set_my_addrs(mut self, my_addrs: Array): diff --git a/crates/test-files/fixtures/stress/tuple_stress.fe b/crates/test-files/fixtures/stress/tuple_stress.fe index 3c5f2bb70c..4613ef0c25 100644 --- a/crates/test-files/fixtures/stress/tuple_stress.fe +++ b/crates/test-files/fixtures/stress/tuple_stress.fe @@ -25,7 +25,7 @@ contract Foo: pub fn read_my_tuple_item10(my_tuple: (u256, u256, u256, u256, u256, u256, u256, u256, u256, u256, address)) -> address: return my_tuple.item10 - pub fn emit_my_event(ctx: Context, my_tuple: (u256, bool, address)): + pub fn emit_my_event(mut ctx: Context, my_tuple: (u256, bool, address)): emit MyEvent(ctx, my_tuple) pub fn set_my_sto_tuple(mut self, my_u256: u256, my_i32: i32): @@ -35,7 +35,7 @@ contract Foo: pub fn get_my_sto_tuple(self) -> (u256, i32): return self.my_sto_tuple.to_mem() - pub fn build_tuple_and_emit(self, ctx: Context): + pub fn build_tuple_and_emit(self, mut ctx: Context): let my_num: u256 = self.my_sto_tuple.item0 let my_tuple: (u256, bool, address) = ( self.my_sto_tuple.item0,