Skip to content

Commit

Permalink
Introduce additional spans in Array and String types (FuelLabs#3499)
Browse files Browse the repository at this point in the history
  • Loading branch information
mohammadfawaz authored Dec 6, 2022
1 parent 3e6f8cf commit 020f2e9
Show file tree
Hide file tree
Showing 18 changed files with 177 additions and 162 deletions.
13 changes: 9 additions & 4 deletions sway-core/src/ir_generation/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ fn convert_resolved_type(
TypeInfo::Numeric => Type::Uint(64),
TypeInfo::Boolean => Type::Bool,
TypeInfo::B256 => Type::B256,
TypeInfo::Str(n) => Type::String(*n),
TypeInfo::Str(n) => Type::String(n.val() as u64),
TypeInfo::Struct { fields, .. } => super::types::get_aggregate_for_types(
type_engine,
context,
Expand All @@ -107,9 +107,14 @@ fn convert_resolved_type(
TypeInfo::Enum { variant_types, .. } => {
create_enum_aggregate(type_engine, context, variant_types).map(Type::Struct)?
}
TypeInfo::Array(elem_type_id, count, _) => {
let elem_type = convert_resolved_typeid(type_engine, context, elem_type_id, span)?;
Type::Array(Aggregate::new_array(context, elem_type, *count as u64))
TypeInfo::Array(elem_type, length) => {
let elem_type =
convert_resolved_typeid(type_engine, context, &elem_type.type_id, span)?;
Type::Array(Aggregate::new_array(
context,
elem_type,
length.val() as u64,
))
}
TypeInfo::Tuple(fields) => {
if fields.is_empty() {
Expand Down
2 changes: 1 addition & 1 deletion sway-core/src/language/literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ impl Literal {

pub(crate) fn to_typeinfo(&self) -> TypeInfo {
match self {
Literal::String(s) => TypeInfo::Str(s.as_str().len() as u64),
Literal::String(s) => TypeInfo::Str(Length::new(s.as_str().len(), s.clone())),
Literal::Numeric(_) => TypeInfo::Numeric,
Literal::U8(_) => TypeInfo::UnsignedInteger(IntegerBits::Eight),
Literal::U16(_) => TypeInfo::UnsignedInteger(IntegerBits::Sixteen),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,9 @@ fn test_function_selector_behavior() {
is_reference: false,
is_mutable: false,
mutability_span: Span::dummy(),
type_id: type_engine.insert_type(TypeInfo::Str(5)),
initial_type_id: type_engine.insert_type(TypeInfo::Str(5)),
type_id: type_engine.insert_type(TypeInfo::Str(Length::new(5, Span::dummy()))),
initial_type_id: type_engine
.insert_type(TypeInfo::Str(Length::new(5, Span::dummy()))),
type_span: Span::dummy(),
},
ty::TyFunctionParameter {
Expand All @@ -225,7 +226,8 @@ fn test_function_selector_behavior() {
is_mutable: false,
mutability_span: Span::dummy(),
type_id: type_engine.insert_type(TypeInfo::UnsignedInteger(IntegerBits::ThirtyTwo)),
initial_type_id: type_engine.insert_type(TypeInfo::Str(5)),
initial_type_id: type_engine
.insert_type(TypeInfo::Str(Length::new(5, Span::dummy()))),
type_span: Span::dummy(),
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ impl ty::TyExpression {
type_engine: &TypeEngine,
) -> CompileResult<ty::TyExpression> {
let return_type = match &lit {
Literal::String(s) => TypeInfo::Str(s.as_str().len() as u64),
Literal::String(s) => TypeInfo::Str(Length::new(s.as_str().len(), s.clone())),
Literal::Numeric(_) => TypeInfo::Numeric,
Literal::U8(_) => TypeInfo::UnsignedInteger(IntegerBits::Eight),
Literal::U16(_) => TypeInfo::UnsignedInteger(IntegerBits::Sixteen),
Expand Down Expand Up @@ -1465,9 +1465,12 @@ impl ty::TyExpression {
contents: Vec::new(),
},
return_type: type_engine.insert_type(TypeInfo::Array(
unknown_type,
0,
unknown_type,
TypeArgument {
type_id: unknown_type,
span: Span::dummy(),
initial_type_id: unknown_type,
},
Length::new(0, Span::dummy()),
)),
span,
},
Expand Down Expand Up @@ -1519,9 +1522,12 @@ impl ty::TyExpression {
contents: typed_contents,
},
return_type: type_engine.insert_type(TypeInfo::Array(
elem_type,
array_count,
elem_type,
TypeArgument {
type_id: elem_type,
span: Span::dummy(),
initial_type_id: elem_type,
},
Length::new(array_count, Span::dummy()),
)), // Maybe?
span,
},
Expand Down Expand Up @@ -1555,9 +1561,7 @@ impl ty::TyExpression {
};

// If the return type is a static array then create a `ty::TyExpressionVariant::ArrayIndex`.
if let TypeInfo::Array(elem_type_id, _, _) =
type_engine.look_up_type_id(prefix_te.return_type)
{
if let TypeInfo::Array(elem_type, _) = type_engine.look_up_type_id(prefix_te.return_type) {
let type_info_u64 = TypeInfo::UnsignedInteger(IntegerBits::SixtyFour);
let ctx = ctx
.with_help_text("")
Expand All @@ -1575,7 +1579,7 @@ impl ty::TyExpression {
prefix: Box::new(prefix_te),
index: Box::new(index_te),
},
return_type: elem_type_id,
return_type: elem_type.type_id,
span,
},
warnings,
Expand Down Expand Up @@ -1927,9 +1931,12 @@ mod tests {
&type_engine,
expr,
type_engine.insert_type(TypeInfo::Array(
type_engine.insert_type(TypeInfo::Boolean),
2,
type_engine.insert_type(TypeInfo::Boolean),
TypeArgument {
type_id: type_engine.insert_type(TypeInfo::Boolean),
span: Span::dummy(),
initial_type_id: type_engine.insert_type(TypeInfo::Boolean),
},
Length::new(2, Span::dummy()),
)),
)
}
Expand Down Expand Up @@ -2041,9 +2048,12 @@ mod tests {
&type_engine,
expr,
type_engine.insert_type(TypeInfo::Array(
type_engine.insert_type(TypeInfo::Boolean),
0,
type_engine.insert_type(TypeInfo::Boolean),
TypeArgument {
type_id: type_engine.insert_type(TypeInfo::Boolean),
span: Span::dummy(),
initial_type_id: type_engine.insert_type(TypeInfo::Boolean),
},
Length::new(0, Span::dummy()),
)),
);
assert!(comp_res.warnings.is_empty() && comp_res.errors.is_empty());
Expand Down
4 changes: 2 additions & 2 deletions sway-core/src/semantic_analysis/namespace/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,11 @@ impl Items {
full_span_for_error = Span::join(full_span_for_error, index_span.clone());
}
(
TypeInfo::Array(elem_ty, _count, _),
TypeInfo::Array(elem_ty, _),
ty::ProjectionKind::ArrayIndex { index_span, .. },
) => {
parent_rover = symbol;
symbol = elem_ty;
symbol = elem_ty.type_id;
symbol_span = index_span.clone();
full_span_for_error = index_span.clone();
}
Expand Down
7 changes: 4 additions & 3 deletions sway-core/src/semantic_analysis/namespace/trait_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ fn are_equal_minus_dynamic_types(type_engine: &TypeEngine, left: TypeId, right:
(TypeInfo::Boolean, TypeInfo::Boolean) => true,
(TypeInfo::B256, TypeInfo::B256) => true,
(TypeInfo::ErrorRecovery, TypeInfo::ErrorRecovery) => true,
(TypeInfo::Str(l), TypeInfo::Str(r)) => l == r,
(TypeInfo::Str(l), TypeInfo::Str(r)) => l.val() == r.val(),
(TypeInfo::UnsignedInteger(l), TypeInfo::UnsignedInteger(r)) => l == r,
(TypeInfo::RawUntypedPtr, TypeInfo::RawUntypedPtr) => true,
(TypeInfo::RawUntypedSlice, TypeInfo::RawUntypedSlice) => true,
Expand Down Expand Up @@ -916,8 +916,9 @@ fn are_equal_minus_dynamic_types(type_engine: &TypeEngine, left: TypeId, right:
})
.unwrap_or(true)
}
(TypeInfo::Array(l0, l1, _), TypeInfo::Array(r0, r1, _)) => {
l1 == r1 && are_equal_minus_dynamic_types(type_engine, l0, r0)
(TypeInfo::Array(l0, l1), TypeInfo::Array(r0, r1)) => {
l1.val() == r1.val()
&& are_equal_minus_dynamic_types(type_engine, l0.type_id, r0.type_id)
}
_ => false,
}
Expand Down
5 changes: 2 additions & 3 deletions sway-core/src/semantic_analysis/node_dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -648,9 +648,8 @@ impl Dependencies {
TypeInfo::Tuple(elems) => self.gather_from_iter(elems.iter(), |deps, elem| {
deps.gather_from_typeinfo(type_engine, &type_engine.look_up_type_id(elem.type_id))
}),
TypeInfo::Array(type_id, _, _) => {
self.gather_from_typeinfo(type_engine, &type_engine.look_up_type_id(*type_id))
}
TypeInfo::Array(elem_type, _) => self
.gather_from_typeinfo(type_engine, &type_engine.look_up_type_id(elem_type.type_id)),
TypeInfo::Struct { fields, .. } => {
self.gather_from_iter(fields.iter(), |deps, field| {
deps.gather_from_typeinfo(
Expand Down
42 changes: 7 additions & 35 deletions sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -954,18 +954,12 @@ fn ty_to_type_info(
}
Ty::Array(bracketed_ty_array_descriptor) => {
let ty_array_descriptor = bracketed_ty_array_descriptor.into_inner();
let initial_elem_ty = type_engine.insert_type(ty_to_type_info(
handler,
type_engine,
*ty_array_descriptor.ty,
)?);
TypeInfo::Array(
initial_elem_ty,
expr_to_usize(handler, *ty_array_descriptor.length)?,
initial_elem_ty,
ty_to_type_argument(handler, type_engine, *ty_array_descriptor.ty)?,
expr_to_length(handler, *ty_array_descriptor.length)?,
)
}
Ty::Str { length, .. } => TypeInfo::Str(expr_to_u64(handler, *length.into_inner())?),
Ty::Str { length, .. } => TypeInfo::Str(expr_to_length(handler, *length.into_inner())?),
Ty::Infer { .. } => TypeInfo::Unknown,
};
Ok(type_info)
Expand Down Expand Up @@ -1929,34 +1923,12 @@ fn fn_arg_to_function_parameter(
Ok(function_parameter)
}

fn expr_to_usize(handler: &Handler, expr: Expr) -> Result<usize, ErrorEmitted> {
fn expr_to_length(handler: &Handler, expr: Expr) -> Result<Length, ErrorEmitted> {
let span = expr.span();
let value = match expr {
Expr::Literal(sway_ast::Literal::Int(lit_int)) => {
match lit_int.ty_opt {
None => (),
Some(..) => {
let error = ConvertParseTreeError::IntTySuffixNotSupported { span };
return Err(handler.emit_err(error.into()));
}
}
match usize::try_from(lit_int.parsed) {
Ok(value) => value,
Err(..) => {
let error = ConvertParseTreeError::IntLiteralOutOfRange { span };
return Err(handler.emit_err(error.into()));
}
}
}
_ => {
let error = ConvertParseTreeError::IntLiteralExpected { span };
return Err(handler.emit_err(error.into()));
}
};
Ok(value)
Ok(Length::new(expr_to_usize(handler, expr)?, span))
}

fn expr_to_u64(handler: &Handler, expr: Expr) -> Result<u64, ErrorEmitted> {
fn expr_to_usize(handler: &Handler, expr: Expr) -> Result<usize, ErrorEmitted> {
let span = expr.span();
let value = match expr {
Expr::Literal(sway_ast::Literal::Int(lit_int)) => {
Expand All @@ -1967,7 +1939,7 @@ fn expr_to_u64(handler: &Handler, expr: Expr) -> Result<u64, ErrorEmitted> {
return Err(handler.emit_err(error.into()));
}
}
match u64::try_from(lit_int.parsed) {
match usize::try_from(lit_int.parsed) {
Ok(value) => value,
Err(..) => {
let error = ConvertParseTreeError::IntLiteralOutOfRange { span };
Expand Down
24 changes: 24 additions & 0 deletions sway-core/src/type_system/length.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use sway_types::{span::Span, Spanned};

/// Describes a fixed length for types that needs it such as arrays and strings
#[derive(Debug, Clone, Hash)]
pub struct Length {
val: usize,
span: Span,
}

impl Length {
pub fn new(val: usize, span: Span) -> Self {
Length { val, span }
}

pub fn val(&self) -> usize {
self.val
}
}

impl Spanned for Length {
fn span(&self) -> Span {
self.span.clone()
}
}
2 changes: 2 additions & 0 deletions sway-core/src/type_system/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod collect_types_metadata;
mod copy_types;
mod create_type_id;
mod length;
mod replace_self_type;
mod resolved_type;
mod trait_constraint;
Expand All @@ -17,6 +18,7 @@ mod unify;
pub(crate) use collect_types_metadata::*;
pub(crate) use copy_types::*;
pub(crate) use create_type_id::*;
pub use length::*;
pub(crate) use replace_self_type::*;
pub(crate) use resolved_type::*;
pub(crate) use trait_constraint::*;
Expand Down
8 changes: 4 additions & 4 deletions sway-core/src/type_system/type_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,10 +518,10 @@ impl TypeEngine {
}
}
}
TypeInfo::Array(type_id, n, initial_type_id) => {
let new_type_id = check!(
TypeInfo::Array(mut elem_ty, n) => {
elem_ty.type_id = check!(
self.resolve_type(
type_id,
elem_ty.type_id,
span,
enforce_type_arguments,
None,
Expand All @@ -532,7 +532,7 @@ impl TypeEngine {
warnings,
errors
);
self.insert_type(TypeInfo::Array(new_type_id, n, initial_type_id))
self.insert_type(TypeInfo::Array(elem_ty, n))
}
TypeInfo::Tuple(mut type_arguments) => {
for type_argument in type_arguments.iter_mut() {
Expand Down
Loading

0 comments on commit 020f2e9

Please sign in to comment.