Complex bitcast recursive tag union pointers when we need them to be opaque

Resolves a discussion on Zulip: https://roc.zulipchat.com/#narrow/stream/231635-compiler-development/topic/When.20recursive.20structs.20aren't.20recursive
This commit is contained in:
Ayaz Hafiz 2022-09-14 16:58:37 -05:00
parent 4b0342ef34
commit 8cd4281173
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
3 changed files with 66 additions and 1 deletions

View file

@ -2432,6 +2432,15 @@ pub fn store_roc_value<'a, 'ctx, 'env>(
.unwrap();
}
} else {
let destination_type = destination
.get_type()
.get_element_type()
.try_into()
.unwrap();
let value =
cast_if_necessary_for_opaque_recursive_pointers(env.builder, value, destination_type);
env.builder.build_store(destination, value);
}
}
@ -2950,6 +2959,29 @@ pub fn load_symbol_and_lambda_set<'a, 'ctx, 'b>(
}
}
/// Cast a value to another value of the same size, but only if their types are not equivalent.
/// This is needed to allow us to interoperate between recursive pointers in unions that are
/// opaque, and well-typed.
///
/// This will no longer be necessary and should be removed after we employ opaque pointers from
/// LLVM.
pub fn cast_if_necessary_for_opaque_recursive_pointers<'ctx>(
builder: &Builder<'ctx>,
from_value: BasicValueEnum<'ctx>,
to_type: BasicTypeEnum<'ctx>,
) -> BasicValueEnum<'ctx> {
if from_value.get_type() != to_type {
complex_bitcast(
builder,
from_value,
to_type,
"bitcast_for_opaque_recursive_pointer",
)
} else {
from_value
}
}
/// Cast a value to another value of the same (or smaller?) size
pub fn cast_basic_basic<'ctx>(
builder: &Builder<'ctx>,