Skip to content

Commit

Permalink
better error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
xunilrj committed Nov 4, 2024
1 parent cc3fec3 commit 73a4be0
Show file tree
Hide file tree
Showing 15 changed files with 206 additions and 14 deletions.
18 changes: 16 additions & 2 deletions sway-core/src/ir_generation/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2194,11 +2194,16 @@ impl<'eng> FnCompiler<'eng> {
let te = self.engines.te();
let de = self.engines.de();

let u8 = Type::get_uint8(context);
let ptr_u8 = Type::new_ptr(context, u8);

let first_argument_expr = &arguments[0];
let first_argument_value = return_on_termination_or_extract!(
self.compile_expression_to_value(context, md_mgr, first_argument_expr)?
);
let first_argument_type = first_argument_value.get_type(context).unwrap(); // TODO unwrap
let first_argument_ptr = save_to_local_return_ptr(self, context, first_argument_value)?;
let first_argument_ptr = self.current_block.append(context).cast_ptr(first_argument_ptr, ptr_u8);

let return_type_elem_ir_type = convert_resolved_type_id(
te,
Expand All @@ -2212,12 +2217,21 @@ impl<'eng> FnCompiler<'eng> {
.new_local_var(context, temp_arg_name, return_type_elem_ir_type, None, false)
.map_err(|ir_error| CompileError::InternalOwned(ir_error.to_string(), Span::dummy()))?;
let dst_local_var_ptr = self.current_block.append(context).get_local(dst_local_var);
let dst_local_var_ptr_as_u8 = self.current_block.append(context).cast_ptr(dst_local_var_ptr, ptr_u8);

// TODO assert both types have the same size
// type check must not allows this to fail
let first_arg_size = first_argument_type.size(&context).in_bytes();
let return_type_size = return_type_elem_ir_type.size(&context).in_bytes();
if first_arg_size != return_type_size {
return Err(CompileError::Internal(
"Types size do not match",
Span::dummy(), // TODO
));
}

let byte_len = return_type_elem_ir_type.size(&context).in_bytes();
self.current_block.append(context)
.mem_copy_bytes(dst_local_var_ptr, first_argument_ptr, byte_len);
.mem_copy_bytes(dst_local_var_ptr_as_u8, first_argument_ptr, byte_len);

let final_value = self.current_block.append(context).load(dst_local_var_ptr);
Ok(TerminatorValue::new(final_value, context))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,23 +134,49 @@ fn type_check_transmute(

let mut ctx = ctx;

// Both type arguments needs to be explicitly defined
if type_arguments.len() != 2 {
return Err(handler.emit_err(CompileError::IntrinsicIncorrectNumTArgs {
name: kind.to_string(),
expected: 2,
span,
}));
}

let src_type = type_arguments[0].type_id;
let return_type = type_arguments[1].type_id;

// Forbid ref and ptr types
fn forbid_ref_ptr_types(engines: &Engines, handler: &Handler, t: TypeId, span: &Span) -> Result<(), ErrorEmitted> {
let types = t.extract_any_including_self(engines, &|t| matches!(t,
TypeInfo::StringSlice |
TypeInfo::RawUntypedPtr |
TypeInfo::RawUntypedSlice |
TypeInfo::Ptr(_) |
TypeInfo::Slice(_) |
TypeInfo::Ref { .. }), vec![], 0);
if !types.is_empty() {
return Err(handler.emit_err(CompileError::TypeNotAllowed {
reason: sway_error::error::TypeNotAllowedReason::NotAllowedInTransmute,
span: span.clone()
}));
} else {
Ok(())
}
}

forbid_ref_ptr_types(engines, handler, src_type, &type_arguments[0].span)?;
forbid_ref_ptr_types(engines, handler, return_type, &type_arguments[1].span)?;

// 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_typed_expr = {
let ctx = ctx
.by_ref()
.with_help_text("")
.with_type_annotation(first_argument_type);
.with_type_annotation(src_type);
ty::TyExpression::type_check(handler, ctx, &arguments[0])?
};

let src_type = type_arguments[0].clone();
// TODO: check types match
// TODO: check they have the same size

let return_type = type_arguments[1].type_id;

Ok((
TyIntrinsicFunctionKind {
kind,
Expand Down
3 changes: 3 additions & 0 deletions sway-error/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2812,6 +2812,9 @@ pub enum TypeNotAllowedReason {

#[error("slices or types containing slices on `const` are not allowed.")]
SliceInConst,

#[error("references, pointers, slices, string slices or types containing any of these are not allowed.")]
NotAllowedInTransmute,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
out
target
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[[package]]
name = "core"
source = "path+from-root-E4EB5F90E61EC58F"

[[package]]
name = "transmute"
source = "member"
dependencies = ["core"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[project]
authors = ["Fuel Labs <contact@fuel.sh>"]
license = "Apache-2.0"
entry = "main.sw"
name = "transmute"

[dependencies]
core = { path = "../../../../../../../../sway-lib-core" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"programType": "script",
"specVersion": "1",
"encodingVersion": "1",
"concreteTypes": [
{
"type": "u64",
"concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
}
],
"metadataTypes": [],
"functions": [
{
"inputs": [],
"name": "main",
"output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0",
"attributes": null
}
],
"loggedTypes": [
{
"logId": "1515152261580153489",
"concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
}
],
"messagesTypes": [],
"configurables": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0x82d76771fa3e7e2cc3c0f9904b45673c9066384f3077cd97e20892c965a096db
Binary file not shown.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
script;

fn main() {
// Missing type arguments
let _ = __transmute(1u64);
let _ = __transmute::<u64>(1u64);

// Wrong source type
let _ = __transmute::<u64, u8>(1u32);

// Different sizes
let _ = __transmute::<u64, u8>(1u64);

// Invalid types
let _ = __transmute::<&u64, &u8>(&1u64);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
source: test/tests/tests.rs
snapshot_kind: text
---
> forc build --path test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute
exit status: 1
output:
Building test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute
Compiling library core (sway-lib-core)
Compiling script transmute (test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute)
error
--> test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/src/main.sw:5:13
|
3 | fn main() {
4 | // Missing type arguments
5 | let _ = __transmute(1u64);
| ^^^^^^^^^^^^^^^^^ Call to "transmute" expects 2 type arguments
6 | let _ = __transmute::<u64>(1u64);
7 |
|
____

error
--> test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/src/main.sw:6:13
|
4 | // Missing type arguments
5 | let _ = __transmute(1u64);
6 | let _ = __transmute::<u64>(1u64);
| ^^^^^^^^^^^^^^^^^^^^^^^^ Call to "transmute" expects 2 type arguments
7 |
8 | // Wrong source type
|
____

error
--> test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/src/main.sw:9:36
|
7 |
8 | // Wrong source type
9 | let _ = __transmute::<u64, u8>(1u32);
| ^^^^ Mismatched types.
expected: u64
found: u32.

10 |
11 | // Different sizes
|
____

error
--> test/src/e2e_vm_tests/test_programs/should_fail/language/intrinsics/transmute/src/main.sw:15:27
|
13 |
14 | // Invalid types
15 | let _ = __transmute::<&u64, &u8>(&1u64);
| ^^^^ references, pointers, slices, string slices or types containing any of these are not allowed.
16 | }
|
____

Aborting due to 4 errors.
error: Failed to compile transmute
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"concreteTypes": [
{
"concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0",
"type": "u64"
}
],
"configurables": [],
"encodingVersion": "1",
"functions": [
{
"attributes": null,
"inputs": [],
"name": "main",
"output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
}
],
"loggedTypes": [],
"messagesTypes": [],
"metadataTypes": [],
"programType": "script",
"specVersion": "1"
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
script;

fn main() -> u64 {
let a = 1u8;
__transmute::<[u8;4], u64>([0u8, 0u8, 0u8, a])
let a = __transmute::<[u8; 8], u64>([0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8]);
let b = __transmute::<(u64,), u64>((2,));
a + b
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
category = "run"
expected_result = { action = "return", value = 1 }
expected_result_new_encoding = { action = "return_data", value = "01" }
expected_result_new_encoding = { action = "return_data", value = "00 00 00 00 00 00 00 03" }
validate_abi = true

0 comments on commit 73a4be0

Please # to comment.