Skip to content

Commit

Permalink
correctly type check type arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
xunilrj committed Nov 11, 2024
1 parent 36df59f commit 3702723
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ fn type_check_transmute(
kind: Intrinsic,
type_arguments: &[TypeArgument],
span: Span,
ctx: TypeCheckContext,
mut ctx: TypeCheckContext,
) -> Result<(TyIntrinsicFunctionKind, TypeId), ErrorEmitted> {
if arguments.len() != 1 {
return Err(handler.emit_err(CompileError::IntrinsicIncorrectNumArgs {
Expand All @@ -131,8 +131,6 @@ fn type_check_transmute(

let engines = ctx.engines();

let mut ctx = ctx;

// Both type arguments needs to be explicitly defined
if type_arguments.len() != 2 {
return Err(handler.emit_err(CompileError::IntrinsicIncorrectNumTArgs {
Expand All @@ -141,9 +139,25 @@ fn type_check_transmute(
span,
}));
}

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

let src_type = ctx
.resolve_type(
handler,
type_arguments[0].type_id,
&type_arguments[0].span,
EnforceTypeArguments::Yes,
None,
)
.unwrap_or_else(|err| engines.te().id_of_error_recovery(err));
let return_type = ctx
.resolve_type(
handler,
type_arguments[1].type_id,
&type_arguments[1].span,
EnforceTypeArguments::Yes,
None,
)
.unwrap_or_else(|err| engines.te().id_of_error_recovery(err));

// Forbid ref and ptr types
fn forbid_ref_ptr_types(
Expand Down Expand Up @@ -182,14 +196,19 @@ fn type_check_transmute(
forbid_ref_ptr_types(engines, handler, return_type, &type_arguments[1].span)?;

// check first argument
let arg_type = engines.te().get(src_type);
let first_argument_typed_expr = {
let ctx = ctx
.by_ref()
.with_help_text("")
.with_type_annotation(src_type);
ty::TyExpression::type_check(handler, ctx, &arguments[0])?
.with_type_annotation(engines.te().insert(engines, (&*arg_type).clone(), type_arguments[0].span.source_id()));
ty::TyExpression::type_check(handler, ctx, &arguments[0]).unwrap()
};

// if handler.has_errors() {
// panic!("{:?}", handler.clone().consume());
// }

Ok((
TyIntrinsicFunctionKind {
kind,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ fn assert(v: bool) {
}

enum SomeEnum {
A: u64
A: u64,
B: u64
}

struct SomeStruct {
a: u64
pub struct SomeStruct {
#[allow(dead_code)]
tag: u64,
#[allow(dead_code)]
value: u64
}

fn main() {
Expand Down Expand Up @@ -72,7 +76,17 @@ fn main() {
assert(tuple_u8_u6_u8.1 == 2);
assert(tuple_u8_u6_u8.2 == 3);

// Check zero sized types
let s = SomeStruct {a: 1};
let zse = __transmute::<SomeStruct, SomeEnum>(s);
// Check struct to enum
let some_struct: SomeStruct = SomeStruct { tag: 0, value: 1 };
let some_enum = __transmute::<SomeStruct, SomeEnum>(some_struct);
match some_enum {
SomeEnum::A(v) => assert(v == 1),
_ => {}
};

// check enum to struct
let some_enum = SomeEnum::B(1);
let some_struct = __transmute::<SomeEnum, SomeStruct>(some_enum);
assert(some_struct.tag == 1);
assert(some_struct.value == 1);
}

0 comments on commit 3702723

Please # to comment.