From 7d5a89f17fa4c237c7e53b0af14fa7c74ba68303 Mon Sep 17 00:00:00 2001 From: xunilrj Date: Thu, 8 Aug 2024 17:26:00 +0100 Subject: [PATCH 1/4] index trait working at LHS --- .../ast_node/expression/intrinsic_function.rs | 83 ++++++--- .../to_parsed_lang/convert_parse_tree.rs | 91 +++++++-- sway-lib-core/src/ops.sw | 48 +++++ .../slice/slice_intrinsics/src/main.sw | 173 +----------------- 4 files changed, 182 insertions(+), 213 deletions(-) diff --git a/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs b/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs index 0df9f72e458..678c5a5e40e 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs @@ -209,54 +209,83 @@ fn type_check_slice( _type_arguments: &[TypeArgument], span: Span, ) -> Result<(ty::TyIntrinsicFunctionKind, TypeId), ErrorEmitted> { - if arguments.len() != 3 { - return Err(handler.emit_err(CompileError::IntrinsicIncorrectNumArgs { - name: kind.to_string(), - expected: 3, - span, - })); - } - + // if arguments.len() != 3 { + // return Err(handler.emit_err(CompileError::IntrinsicIncorrectNumArgs { + // name: kind.to_string(), + // expected: 3, + // span, + // })); + // } + // let type_engine = ctx.engines.te(); let engines = ctx.engines(); - // start index argument - let start_type = type_engine.insert( + let uint64 = type_engine.insert( engines, TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), None, ); - let start_ty_expr = { + + // check first argument + let first_argument_span = arguments[0].span.clone(); + let first_argument_type = type_engine.insert(engines, TypeInfo::Unknown, None); + let first_argument_ty_expr = { + let ctx = ctx + .by_ref() + .with_help_text("") + .with_type_annotation(first_argument_type); + ty::TyExpression::type_check(handler, ctx, &arguments[0])? + }; + + // start index argument + let start_ty_expr = if let Some(v) = arguments.get(1) { + let start_type = type_engine.insert( + engines, + TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), + None, + ); + let ctx = ctx .by_ref() .with_help_text("") .with_type_annotation(start_type); ty::TyExpression::type_check(handler, ctx, &arguments[1])? + } else { + ty::TyExpression { + expression: ty::TyExpressionVariant::Literal(Literal::U64(0)), + return_type: uint64, + span: Span::dummy(), + } }; // end index argument - let end_type = type_engine.insert( - engines, - TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), - None, - ); - let end_ty_expr = { + let end_ty_expr = if let Some(v) = arguments.get(2) { + let end_type = type_engine.insert( + engines, + TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), + None, + ); let ctx = ctx .by_ref() .with_help_text("") .with_type_annotation(end_type); ty::TyExpression::type_check(handler, ctx, &arguments[2])? - }; + } else { + let len = match &*type_engine.get(first_argument_ty_expr.return_type) { + TypeInfo::Ref { + referenced_type, .. + } => match &*type_engine.get(referenced_type.type_id) { + TypeInfo::Array(_, len) => len.val(), + x => unreachable!("{x:?}"), + }, + _ => unreachable!(), + }; - // check first argument - let first_argument_span = arguments[0].span.clone(); - let first_argument_type = type_engine.insert(engines, TypeInfo::Unknown, None); - let first_argument_ty_expr = { - let ctx = ctx - .by_ref() - .with_help_text("") - .with_type_annotation(first_argument_type); - ty::TyExpression::type_check(handler, ctx, &arguments[0])? + ty::TyExpression { + expression: ty::TyExpressionVariant::Literal(Literal::U64(len as u64)), + return_type: uint64, + span: Span::dummy(), + } }; // statically check start and end, if possible diff --git a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs index 4ed2e8799ab..180157420cc 100644 --- a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs +++ b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs @@ -2506,6 +2506,31 @@ fn expr_to_expression( Ok(expression) } +fn fn_call_index_mut( + name: &'static str, + op_span: Span, + span: Span, + args: &[Expression], +) -> Result { + let call_path_binding = TypeBinding { + inner: CallPath { + prefixes: vec![], + suffix: Ident::new_with_override(name.into(), op_span.clone()), + is_absolute: true, + }, + type_arguments: TypeArgs::Regular(vec![]), + span: op_span, + }; + Ok(Expression { + kind: ExpressionKind::FunctionApplication(Box::new(FunctionApplicationExpression { + call_path_binding, + resolved_call_path_binding: None, + arguments: args.to_vec(), + })), + span, + }) +} + fn op_call( name: &'static str, op_span: Span, @@ -4441,24 +4466,54 @@ fn assignable_to_expression( kind: ExpressionKind::Variable(name), span, }, - ElementAccess::Index { target, arg } => Expression { - kind: ExpressionKind::ArrayIndex(ArrayIndexExpression { - prefix: Box::new(element_access_to_expression( - context, - handler, - engines, - *target, - span.clone(), - )?), - index: Box::new(expr_to_expression( - context, - handler, - engines, - *arg.into_inner(), - )?), - }), - span, - }, + ElementAccess::Index { target, arg } => { + let target = + element_access_to_expression(context, handler, engines, *target, span.clone())?; + let target = Expression { + kind: ExpressionKind::IntrinsicFunction(IntrinsicFunctionExpression { + name: Ident::new_no_span("__slice".to_string()), + kind_binding: TypeBinding { + inner: Intrinsic::Slice, + type_arguments: TypeArgs::Regular(vec![]), + span: Span::dummy(), + }, + arguments: vec![Expression { + kind: ExpressionKind::Ref(RefExpression { + to_mutable_value: true, + value: Box::new(target), + }), + span: span.clone(), + }], + }), + span: span.clone(), + }; + + let arg = expr_to_expression(context, handler, engines, *arg.inner)?; + let call = + fn_call_index_mut("index_mut", arg.span(), span.clone(), &vec![target, arg])?; + Expression { + kind: ExpressionKind::Deref(Box::new(call)), + span, + } + } + // ElementAccess::Index { target, arg } => Expression { + // kind: ExpressionKind::ArrayIndex(ArrayIndexExpression { + // prefix: Box::new(element_access_to_expression( + // context, + // handler, + // engines, + // *target, + // span.clone(), + // )?), + // index: Box::new(expr_to_expression( + // context, + // handler, + // engines, + // *arg.into_inner(), + // )?), + // }), + // span, + // }, ElementAccess::FieldProjection { target, name, .. } => { let mut idents = vec![&name]; let mut base = &*target; diff --git a/sway-lib-core/src/ops.sw b/sway-lib-core/src/ops.sw index 7dd28960cb3..93a095871a5 100644 --- a/sway-lib-core/src/ops.sw +++ b/sway-lib-core/src/ops.sw @@ -1258,3 +1258,51 @@ pub fn ok_str_eq() { assert("" != "a"); assert("a" != "b"); } + +// Index +pub trait Index { + type Output; + fn index(self, index: T) -> &Self::Output; +} + +pub trait IndexMut { + type Output; + fn index_mut(self, index: T) -> &mut Self::Output; +} + +impl Index for &__slice[T] { + type Output = T; + + fn index(self, index: u64) -> &Self::Output { + if index >= self.len() { + __revert(999); + } + __elem_at(self, index) + } +} + +impl Index for &mut __slice[T] { + type Output = T; + + fn index(self, index: u64) -> &Self::Output { + if index >= self.len() { + __revert(999); + } + __elem_at(self, index) + } +} + +impl IndexMut for &mut __slice[T] { + type Output = T; + + fn index_mut(self, index: u64) -> &mut T { + if index >= self.len() { + __revert(999); + } + __elem_at(self, index) + } +} + +pub fn index_mut(target: &mut __slice[T], index: u64) -> &mut T { + target.index_mut(index) +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/slice/slice_intrinsics/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/slice/slice_intrinsics/src/main.sw index 8b094c836ab..819fdae0f53 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/slice/slice_intrinsics/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/slice/slice_intrinsics/src/main.sw @@ -1,104 +1,5 @@ script; -use utils::*; - -fn alloc_slice(len: u64) -> &mut __slice[T] { - let size_in_bytes = len * __size_of::(); - let ptr = asm(size_in_bytes: size_in_bytes) { - aloc size_in_bytes; - hp: raw_ptr - }; - asm(buf: (ptr, len)) { - buf: &mut __slice[T] - } -} - -fn realloc_slice(old: &mut __slice[T], len: u64) -> &mut __slice[T] { - let old_ptr = old.ptr(); - let old_len_in_bytes = old.len() * __size_of::(); - - let new_len_in_bytes = len * __size_of::(); - let new_ptr = asm(new_len_in_bytes: new_len_in_bytes, old_ptr: old_ptr, old_len_in_bytes: old_len_in_bytes) { - aloc new_len_in_bytes; - mcp hp old_ptr old_len_in_bytes; - hp: raw_ptr - }; - - asm(buf: (new_ptr, len)) { - buf: &mut __slice[T] - } -} - -pub struct Vec { - buf: &mut __slice[T], - len: u64, -} - -impl Dbg for Vec { - fn dbg(self) { - ( - "Vec { buf: (ptr: ", - asm(v: self.buf.ptr()) { v: u64 }, - ", len: ", - self.buf.len(), - "), len: ", - self.len, - ")" - ).dbg(); - } -} - - -impl Vec { - pub fn new() -> Self { - Self { - buf: alloc_slice::(0), - len: 0 - } - } - - pub fn push(ref mut self, item: T) { - "Vec::push(...)".dbgln(); - (" ", self).dbgln(); - - let new_item_idx = self.len; - let current_cap = self.buf.len(); - if new_item_idx >= current_cap { - let new_cap = if current_cap == 0 { - 1 - } else { - current_cap * 2 - }; - self.buf = realloc_slice(self.buf, new_cap); - (" After realloc: ", self).dbgln(); - } - - let v: &mut T = __elem_at(self.buf, new_item_idx); - - let buffer_addr = asm(v: self.buf.ptr()) { v: u64 }; - let elem_addr = asm(v: v) { v: u64 }; - (" elem ", new_item_idx, " at ", elem_addr, " buffer offset (in bytes): ", elem_addr - buffer_addr).dbgln(); - *v = item; - - self.len += 1; - - (" ", self).dbgln(); - } - - pub fn get(self, index: u64) -> T { - ("Vec::get(", index, ")").dbgln(); - (" ", self).dbgln(); - - let item: &mut T = __elem_at(self.buf, index); - - let buffer_addr = asm(v: self.buf.ptr()) { v: u64 }; - let elem_addr = asm(v: item) { v: u64 }; - (" element ", index, " at ", elem_addr, " buffer offset (in bytes): ", elem_addr - buffer_addr).dbgln(); - - *item - } -} - fn assert(l: T, r: T) where T: Eq + AbiEncode @@ -110,74 +11,10 @@ where } } -fn type_check() { - let immutable_array: [u64; 5] = [1, 2, 3, 4, 5]; - let _: &u64 = __elem_at(&immutable_array, 0); - - let mut mutable_array: [u64; 5] = [1, 2, 3, 4, 5]; - let _: &u64 = __elem_at(&mutable_array, 0); - let _: &mut u64 = __elem_at(&mut mutable_array, 0); - let _: &u64 = __elem_at(&mut mutable_array, 0); - - let immutable_slice: &__slice[u64] = __slice(&immutable_array, 0, 5); - let _: &u64 = __elem_at(immutable_slice, 0); - - let mutable_slice: &mut __slice[u64] = __slice(&mut mutable_array, 0, 5); - let _: &mut u64 = __elem_at(mutable_slice, 0); - let _: &u64 = __elem_at(mutable_slice, 0); -} - fn main() { - type_check(); - - // index arrays - let some_array: [u64; 5] = [1, 2, 3, 4, 5]; - assert(1, *__elem_at(&some_array, 0)); - assert(2, *__elem_at(&some_array, 1)); - assert(3, *__elem_at(&some_array, 2)); - assert(4, *__elem_at(&some_array, 3)); - assert(5, *__elem_at(&some_array, 4)); - - // slice arrays - let some_slice: &__slice[u64] = __slice(&some_array, 0, 5); - assert(1, *__elem_at(some_slice, 0)); - assert(2, *__elem_at(some_slice, 1)); - assert(3, *__elem_at(some_slice, 2)); - assert(4, *__elem_at(some_slice, 3)); - assert(5, *__elem_at(some_slice, 4)); - - // slice another slice - let another_slice: &__slice[u64] = __slice(some_slice, 1, 4); - assert(2, *__elem_at(another_slice, 0)); - assert(3, *__elem_at(another_slice, 1)); - assert(4, *__elem_at(another_slice, 2)); - - // Vec impl using slices - let mut v: Vec = Vec::new(); - v.push(1); - assert(v.get(0), 1); - - v.push(2); - v.push(3); - assert(v.get(0), 1); - assert(v.get(1), 2); - assert(v.get(2), 3); - - v.push(4); - v.push(5); - v.push(6); - v.push(7); - assert(v.get(0), 1); - assert(v.get(1), 2); - assert(v.get(2), 3); - assert(v.get(3), 4); - assert(v.get(4), 5); - assert(v.get(5), 6); - assert(v.get(6), 7); - - //indices as expressions - assert(2, *__elem_at(&some_array, v.get(0))); - - let _some_slice: &__slice[u64] = __slice(&some_array, v.get(0), v.get(4)); - assert(2, *__elem_at(some_slice, v.get(0))); + let mut a: [u64; 5] = [1, 2, 3, 4, 5]; + assert(*__elem_at(&a, 0), 1); + a[0] = 2; + assert(*__elem_at(&a, 0), 2); + //a[5] = 2; } From e45ee5a7507852193d3a36a900c36fdc8136414d Mon Sep 17 00:00:00 2001 From: xunilrj Date: Fri, 9 Aug 2024 10:21:29 +0100 Subject: [PATCH 2/4] index desugar on RHS --- .../to_parsed_lang/convert_parse_tree.rs | 99 +++++++++++-------- sway-lib-core/src/ops.sw | 4 + .../slice/slice_intrinsics/src/main.sw | 32 +++++- 3 files changed, 91 insertions(+), 44 deletions(-) diff --git a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs index 180157420cc..438d89bb23b 100644 --- a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs +++ b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs @@ -44,7 +44,7 @@ use sway_types::{ use sway_types::{Ident, Span, Spanned}; use std::{ - collections::HashSet, convert::TryFrom, iter, mem::MaybeUninit, str::FromStr, sync::Arc, + collections::HashSet, convert::TryFrom, iter, mem::MaybeUninit, ops::Deref, str::FromStr, sync::Arc }; pub fn convert_parse_tree( @@ -2173,17 +2173,16 @@ fn expr_to_expression( let kind = expr_func_app_to_expression_kind(context, handler, engines, func, args)?; Expression { kind, span } } - Expr::Index { target, arg } => Expression { - kind: ExpressionKind::ArrayIndex(ArrayIndexExpression { - prefix: Box::new(expr_to_expression(context, handler, engines, *target)?), - index: Box::new(expr_to_expression( - context, - handler, - engines, - *arg.into_inner(), - )?), - }), - span, + // this index is not "under" ref (&) or mut ref (&mut), so + // we need to deref it here + Expr::Index { target, arg } => { + let target = expr_to_expression(context, handler, engines, *target)?; + let arg = expr_to_expression(context, handler, engines, *arg.inner)?; + let expr = desugar_into_index_trait(false, arg.span(), span.clone(), target, arg)?; + Expression { + kind: ExpressionKind::Deref(Box::new(expr)), + span, + } }, Expr::MethodCall { target, @@ -2270,12 +2269,21 @@ fn expr_to_expression( }, Expr::Ref { mut_token, expr, .. - } => Expression { - kind: ExpressionKind::Ref(RefExpression { - to_mutable_value: mut_token.is_some(), - value: Box::new(expr_to_expression(context, handler, engines, *expr)?), - }), - span, + } => { + match *expr { + Expr::Index { target, arg } => { + let target = expr_to_expression(context, handler, engines, *target)?; + let arg = expr_to_expression(context, handler, engines, *arg.inner)?; + desugar_into_index_trait(mut_token.is_some(), arg.span(), span.clone(), target, arg)? + }, + expr => Expression { + kind: ExpressionKind::Ref(RefExpression { + to_mutable_value: mut_token.is_some(), + value: Box::new(expr_to_expression(context, handler, engines, expr)?), + }), + span, + } + } }, Expr::Deref { expr, .. } => Expression { kind: ExpressionKind::Deref(Box::new(expr_to_expression( @@ -2506,12 +2514,38 @@ fn expr_to_expression( Ok(expression) } -fn fn_call_index_mut( - name: &'static str, +fn desugar_into_index_trait( + mutable: bool, op_span: Span, span: Span, - args: &[Expression], + target: Expression, + arg: Expression, ) -> Result { + let target = Expression { + kind: ExpressionKind::IntrinsicFunction(IntrinsicFunctionExpression { + name: Ident::new_no_span("__slice".to_string()), + kind_binding: TypeBinding { + inner: Intrinsic::Slice, + type_arguments: TypeArgs::Regular(vec![]), + span: Span::dummy(), + }, + arguments: vec![Expression { + kind: ExpressionKind::Ref(RefExpression { + to_mutable_value: mutable, + value: Box::new(target), + }), + span: span.clone(), + }], + }), + span: span.clone(), + }; + + let name = if mutable { + "index_mut" + } else { + "index" + }; + let call_path_binding = TypeBinding { inner: CallPath { prefixes: vec![], @@ -2525,7 +2559,7 @@ fn fn_call_index_mut( kind: ExpressionKind::FunctionApplication(Box::new(FunctionApplicationExpression { call_path_binding, resolved_call_path_binding: None, - arguments: args.to_vec(), + arguments: vec![target, arg], })), span, }) @@ -4469,28 +4503,9 @@ fn assignable_to_expression( ElementAccess::Index { target, arg } => { let target = element_access_to_expression(context, handler, engines, *target, span.clone())?; - let target = Expression { - kind: ExpressionKind::IntrinsicFunction(IntrinsicFunctionExpression { - name: Ident::new_no_span("__slice".to_string()), - kind_binding: TypeBinding { - inner: Intrinsic::Slice, - type_arguments: TypeArgs::Regular(vec![]), - span: Span::dummy(), - }, - arguments: vec![Expression { - kind: ExpressionKind::Ref(RefExpression { - to_mutable_value: true, - value: Box::new(target), - }), - span: span.clone(), - }], - }), - span: span.clone(), - }; - let arg = expr_to_expression(context, handler, engines, *arg.inner)?; let call = - fn_call_index_mut("index_mut", arg.span(), span.clone(), &vec![target, arg])?; + desugar_into_index_trait(true, arg.span(), span.clone(), target, arg)?; Expression { kind: ExpressionKind::Deref(Box::new(call)), span, diff --git a/sway-lib-core/src/ops.sw b/sway-lib-core/src/ops.sw index 93a095871a5..fc4fb7713e9 100644 --- a/sway-lib-core/src/ops.sw +++ b/sway-lib-core/src/ops.sw @@ -1303,6 +1303,10 @@ impl IndexMut for &mut __slice[T] { } } +pub fn index(target: &__slice[T], index: u64) -> &T { + target.index(index) +} + pub fn index_mut(target: &mut __slice[T], index: u64) -> &mut T { target.index_mut(index) } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/slice/slice_intrinsics/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/slice/slice_intrinsics/src/main.sw index 819fdae0f53..1ccaeed6607 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/slice/slice_intrinsics/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/slice/slice_intrinsics/src/main.sw @@ -1,5 +1,27 @@ script; +fn assert_refs(l: &T, r: &T) +where + T: Eq + AbiEncode +{ + if *l != *r { + __log(*l); + __log(*r); + __revert(1) + } +} + +fn assert_mut_refs(l: &mut T, r: &mut T) +where + T: Eq + AbiEncode +{ + if *l != *r { + __log(*l); + __log(*r); + __revert(1) + } +} + fn assert(l: T, r: T) where T: Eq + AbiEncode @@ -13,8 +35,14 @@ where fn main() { let mut a: [u64; 5] = [1, 2, 3, 4, 5]; - assert(*__elem_at(&a, 0), 1); + + assert(a[0], 1); + assert_refs(&a[0], &1); + assert_mut_refs(&mut a[0], &mut 1); a[0] = 2; - assert(*__elem_at(&a, 0), 2); + assert(a[0], 2); + assert_refs(&a[0], &2); + assert_mut_refs(&mut a[0], &mut 2); + //a[5] = 2; } From 93d5aa9cbc778f57e182f151c81bcf1c5200de0b Mon Sep 17 00:00:00 2001 From: xunilrj Date: Fri, 9 Aug 2024 10:28:28 +0100 Subject: [PATCH 3/4] removing Index typed expressions --- .../src/language/parsed/expression/mod.rs | 2 -- .../ast_node/expression/typed_expression.rs | 28 ------------------- .../semantic_analysis/node_dependencies.rs | 3 -- .../src/semantic_analysis/symbol_resolve.rs | 4 --- .../to_parsed_lang/convert_parse_tree.rs | 2 +- 5 files changed, 1 insertion(+), 38 deletions(-) diff --git a/sway-core/src/language/parsed/expression/mod.rs b/sway-core/src/language/parsed/expression/mod.rs index 90d41fbf19b..24883d349d4 100644 --- a/sway-core/src/language/parsed/expression/mod.rs +++ b/sway-core/src/language/parsed/expression/mod.rs @@ -461,7 +461,6 @@ pub enum ExpressionKind { DelineatedPath(Box), /// A cast of a hash to an ABI for calling a contract. AbiCast(Box), - ArrayIndex(ArrayIndexExpression), StorageAccess(StorageAccessExpression), IntrinsicFunction(IntrinsicFunctionExpression), /// A control flow element which loops continually until some boolean expression evaluates as @@ -532,7 +531,6 @@ impl PartialEqWithEngines for ExpressionKind { lhs.eq(rhs, ctx) } (ExpressionKind::AbiCast(lhs), ExpressionKind::AbiCast(rhs)) => lhs.eq(rhs, ctx), - (ExpressionKind::ArrayIndex(lhs), ExpressionKind::ArrayIndex(rhs)) => lhs.eq(rhs, ctx), (ExpressionKind::StorageAccess(lhs), ExpressionKind::StorageAccess(rhs)) => { lhs.eq(rhs, ctx) } diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index 47478b59e7b..f9cdbf53f75 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -324,13 +324,6 @@ impl ty::TyExpression { ExpressionKind::Array(array_expression) => { Self::type_check_array(handler, ctx.by_ref(), &array_expression.contents, span) } - ExpressionKind::ArrayIndex(ArrayIndexExpression { prefix, index }) => { - let ctx = ctx - .by_ref() - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)) - .with_help_text(""); - Self::type_check_array_index(handler, ctx, prefix, index, span) - } ExpressionKind::StorageAccess(StorageAccessExpression { namespace_names, field_names, @@ -2224,27 +2217,6 @@ impl ty::TyExpression { indices.push(ty::ProjectionKind::TupleField { index, index_span }); expr = prefix; } - ExpressionKind::ArrayIndex(ArrayIndexExpression { prefix, index }) => { - let type_info_u64 = TypeInfo::UnsignedInteger(IntegerBits::SixtyFour); - let ctx = ctx - .by_ref() - .with_help_text("Array index must be of type \"u64\".") - .with_type_annotation(type_engine.insert( - engines, - type_info_u64, - None, - )); - let typed_index = - ty::TyExpression::type_check(handler, ctx, index.as_ref()) - .unwrap_or_else(|err| { - ty::TyExpression::error(err, span.clone(), engines) - }); - indices.push(ty::ProjectionKind::ArrayIndex { - index: Box::new(typed_index), - index_span: index.span(), - }); - expr = prefix; - } _ => { return Err( handler.emit_err(CompileError::InvalidExpressionOnLhs { span }) diff --git a/sway-core/src/semantic_analysis/node_dependencies.rs b/sway-core/src/semantic_analysis/node_dependencies.rs index 1b8e993e323..1ff1e07b273 100644 --- a/sway-core/src/semantic_analysis/node_dependencies.rs +++ b/sway-core/src/semantic_analysis/node_dependencies.rs @@ -586,9 +586,6 @@ impl Dependencies { .gather_from_iter(array_expression.contents.iter(), |deps, expr| { deps.gather_from_expr(engines, expr) }), - ExpressionKind::ArrayIndex(ArrayIndexExpression { prefix, index, .. }) => self - .gather_from_expr(engines, prefix) - .gather_from_expr(engines, index), ExpressionKind::Struct(struct_expression) => { let StructExpression { call_path_binding, diff --git a/sway-core/src/semantic_analysis/symbol_resolve.rs b/sway-core/src/semantic_analysis/symbol_resolve.rs index 60ac3da6a53..51941d362ff 100644 --- a/sway-core/src/semantic_analysis/symbol_resolve.rs +++ b/sway-core/src/semantic_analysis/symbol_resolve.rs @@ -610,10 +610,6 @@ impl ResolveSymbols for ExpressionKind { expr.abi_name.resolve_symbols(handler, ctx.by_ref()); expr.address.resolve_symbols(handler, ctx.by_ref()); } - ExpressionKind::ArrayIndex(expr) => { - expr.index.resolve_symbols(handler, ctx.by_ref()); - expr.prefix.resolve_symbols(handler, ctx.by_ref()); - } ExpressionKind::StorageAccess(_expr) => {} ExpressionKind::IntrinsicFunction(expr) => { expr.arguments diff --git a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs index 438d89bb23b..487d1853589 100644 --- a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs +++ b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs @@ -44,7 +44,7 @@ use sway_types::{ use sway_types::{Ident, Span, Spanned}; use std::{ - collections::HashSet, convert::TryFrom, iter, mem::MaybeUninit, ops::Deref, str::FromStr, sync::Arc + collections::HashSet, convert::TryFrom, iter, mem::MaybeUninit, str::FromStr, sync::Arc }; pub fn convert_parse_tree( From e0cf28860ab72659ef2f22527d912a302a70c4ed Mon Sep 17 00:00:00 2001 From: xunilrj Date: Fri, 9 Aug 2024 10:32:10 +0100 Subject: [PATCH 4/4] clippy and fmt issues --- .../ast_node/expression/intrinsic_function.rs | 4 +- .../ast_node/expression/typed_expression.rs | 79 ------------------- .../to_parsed_lang/convert_parse_tree.rs | 45 ++++++----- sway-lsp/src/traverse/parsed_tree.rs | 31 +++----- 4 files changed, 37 insertions(+), 122 deletions(-) diff --git a/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs b/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs index 678c5a5e40e..8d7594f08b0 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/intrinsic_function.rs @@ -238,7 +238,7 @@ fn type_check_slice( }; // start index argument - let start_ty_expr = if let Some(v) = arguments.get(1) { + let start_ty_expr = if arguments.get(1).is_some() { let start_type = type_engine.insert( engines, TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), @@ -259,7 +259,7 @@ fn type_check_slice( }; // end index argument - let end_ty_expr = if let Some(v) = arguments.get(2) { + let end_ty_expr = if arguments.get(2).is_some() { let end_type = type_engine.insert( engines, TypeInfo::UnsignedInteger(IntegerBits::SixtyFour), diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index f9cdbf53f75..47115ec611e 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -1876,85 +1876,6 @@ impl ty::TyExpression { }) } - fn type_check_array_index( - handler: &Handler, - mut ctx: TypeCheckContext, - prefix: &Expression, - index: &Expression, - span: Span, - ) -> Result { - let type_engine = ctx.engines.te(); - let engines = ctx.engines(); - - let mut current_prefix_te = Box::new({ - let ctx = ctx - .by_ref() - .with_help_text("") - .with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None)); - - ty::TyExpression::type_check(handler, ctx, prefix)? - }); - - let mut current_type = type_engine.get_unaliased(current_prefix_te.return_type); - - let prefix_type_id = current_prefix_te.return_type; - let prefix_span = current_prefix_te.span.clone(); - - // Create the prefix part of the final array index expression. - // This might be an expression that directly evaluates to an array type, - // or an arbitrary number of dereferencing expressions where the last one - // dereference to an array type. - // - // We will either hit an array at the end or return an error, so the - // loop cannot be endless. - while !current_type.is_array() { - match &*current_type { - TypeInfo::Ref { - referenced_type, .. - } => { - let referenced_type_id = referenced_type.type_id; - - current_prefix_te = Box::new(ty::TyExpression { - expression: ty::TyExpressionVariant::Deref(current_prefix_te), - return_type: referenced_type_id, - span: prefix_span.clone(), - }); - - current_type = type_engine.get_unaliased(referenced_type_id); - } - TypeInfo::ErrorRecovery(err) => return Err(*err), - _ => { - return Err(handler.emit_err(CompileError::NotIndexable { - actually: engines.help_out(prefix_type_id).to_string(), - span: prefix_span, - })) - } - }; - } - - let TypeInfo::Array(array_type_argument, _) = &*current_type else { - panic!("The current type must be an array."); - }; - - let index_te = { - let type_info_u64 = TypeInfo::UnsignedInteger(IntegerBits::SixtyFour); - let ctx = ctx - .with_help_text("Array index must be of type \"u64\".") - .with_type_annotation(type_engine.insert(engines, type_info_u64, None)); - - ty::TyExpression::type_check(handler, ctx, index)? - }; - - Ok(ty::TyExpression { - expression: ty::TyExpressionVariant::ArrayIndex { - prefix: current_prefix_te, - index: Box::new(index_te), - }, - return_type: array_type_argument.type_id, - span, - }) - } - fn type_check_intrinsic_function( handler: &Handler, ctx: TypeCheckContext, diff --git a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs index 487d1853589..a2d579cb871 100644 --- a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs +++ b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs @@ -44,7 +44,7 @@ use sway_types::{ use sway_types::{Ident, Span, Spanned}; use std::{ - collections::HashSet, convert::TryFrom, iter, mem::MaybeUninit, str::FromStr, sync::Arc + collections::HashSet, convert::TryFrom, iter, mem::MaybeUninit, str::FromStr, sync::Arc, }; pub fn convert_parse_tree( @@ -2183,7 +2183,7 @@ fn expr_to_expression( kind: ExpressionKind::Deref(Box::new(expr)), span, } - }, + } Expr::MethodCall { target, path_seg, @@ -2269,21 +2269,25 @@ fn expr_to_expression( }, Expr::Ref { mut_token, expr, .. - } => { - match *expr { - Expr::Index { target, arg } => { - let target = expr_to_expression(context, handler, engines, *target)?; - let arg = expr_to_expression(context, handler, engines, *arg.inner)?; - desugar_into_index_trait(mut_token.is_some(), arg.span(), span.clone(), target, arg)? - }, - expr => Expression { - kind: ExpressionKind::Ref(RefExpression { - to_mutable_value: mut_token.is_some(), - value: Box::new(expr_to_expression(context, handler, engines, expr)?), - }), - span, - } + } => match *expr { + Expr::Index { target, arg } => { + let target = expr_to_expression(context, handler, engines, *target)?; + let arg = expr_to_expression(context, handler, engines, *arg.inner)?; + desugar_into_index_trait( + mut_token.is_some(), + arg.span(), + span.clone(), + target, + arg, + )? } + expr => Expression { + kind: ExpressionKind::Ref(RefExpression { + to_mutable_value: mut_token.is_some(), + value: Box::new(expr_to_expression(context, handler, engines, expr)?), + }), + span, + }, }, Expr::Deref { expr, .. } => Expression { kind: ExpressionKind::Deref(Box::new(expr_to_expression( @@ -2540,11 +2544,7 @@ fn desugar_into_index_trait( span: span.clone(), }; - let name = if mutable { - "index_mut" - } else { - "index" - }; + let name = if mutable { "index_mut" } else { "index" }; let call_path_binding = TypeBinding { inner: CallPath { @@ -4504,8 +4504,7 @@ fn assignable_to_expression( let target = element_access_to_expression(context, handler, engines, *target, span.clone())?; let arg = expr_to_expression(context, handler, engines, *arg.inner)?; - let call = - desugar_into_index_trait(true, arg.span(), span.clone(), target, arg)?; + let call = desugar_into_index_trait(true, arg.span(), span.clone(), target, arg)?; Expression { kind: ExpressionKind::Deref(Box::new(call)), span, diff --git a/sway-lsp/src/traverse/parsed_tree.rs b/sway-lsp/src/traverse/parsed_tree.rs index 880915f915b..c079b7f475b 100644 --- a/sway-lsp/src/traverse/parsed_tree.rs +++ b/sway-lsp/src/traverse/parsed_tree.rs @@ -18,20 +18,19 @@ use sway_core::{ decl_engine::parsed_id::ParsedDeclId, language::{ parsed::{ - AbiCastExpression, AbiDeclaration, AmbiguousPathExpression, ArrayExpression, - ArrayIndexExpression, AstNode, AstNodeContent, ConfigurableDeclaration, - ConstantDeclaration, Declaration, DelineatedPathExpression, EnumDeclaration, - EnumVariant, Expression, ExpressionKind, ForLoopExpression, - FunctionApplicationExpression, FunctionDeclaration, FunctionParameter, IfExpression, - ImplItem, ImplSelfOrTrait, ImportType, IncludeStatement, IntrinsicFunctionExpression, - LazyOperatorExpression, MatchExpression, MethodApplicationExpression, MethodName, - ParseModule, ParseProgram, ParseSubmodule, QualifiedPathType, ReassignmentExpression, - ReassignmentTarget, RefExpression, Scrutinee, StorageAccessExpression, - StorageDeclaration, StorageEntry, StorageField, StorageNamespace, StructDeclaration, - StructExpression, StructExpressionField, StructField, StructScrutineeField, - SubfieldExpression, Supertrait, TraitDeclaration, TraitFn, TraitItem, - TraitTypeDeclaration, TupleIndexExpression, TypeAliasDeclaration, UseStatement, - VariableDeclaration, WhileLoopExpression, + AbiCastExpression, AbiDeclaration, AmbiguousPathExpression, ArrayExpression, AstNode, + AstNodeContent, ConfigurableDeclaration, ConstantDeclaration, Declaration, + DelineatedPathExpression, EnumDeclaration, EnumVariant, Expression, ExpressionKind, + ForLoopExpression, FunctionApplicationExpression, FunctionDeclaration, + FunctionParameter, IfExpression, ImplItem, ImplSelfOrTrait, ImportType, + IncludeStatement, IntrinsicFunctionExpression, LazyOperatorExpression, MatchExpression, + MethodApplicationExpression, MethodName, ParseModule, ParseProgram, ParseSubmodule, + QualifiedPathType, ReassignmentExpression, ReassignmentTarget, RefExpression, + Scrutinee, StorageAccessExpression, StorageDeclaration, StorageEntry, StorageField, + StorageNamespace, StructDeclaration, StructExpression, StructExpressionField, + StructField, StructScrutineeField, SubfieldExpression, Supertrait, TraitDeclaration, + TraitFn, TraitItem, TraitTypeDeclaration, TupleIndexExpression, TypeAliasDeclaration, + UseStatement, VariableDeclaration, WhileLoopExpression, }, CallPathTree, HasSubmodules, Literal, }, @@ -308,10 +307,6 @@ impl Parse for Expression { ExpressionKind::AbiCast(abi_cast_expression) => { abi_cast_expression.parse(ctx); } - ExpressionKind::ArrayIndex(ArrayIndexExpression { prefix, index, .. }) => { - prefix.parse(ctx); - index.parse(ctx); - } ExpressionKind::StorageAccess(StorageAccessExpression { field_names, namespace_names,