aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2018-02-23 15:25:42 +0100
committerBen Noordhuis <info@bnoordhuis.nl>2018-02-23 15:55:57 +0100
commitf11b9480192dea44acb92cb9edd7a91c7c73cd2f (patch)
tree5172a83b0a23842d661d4e2d8bf74587e902913d /src
parentb66547e98c9034e52c5647735b47dc24939c8d15 (diff)
downloadzig-f11b9480192dea44acb92cb9edd7a91c7c73cd2f.tar.gz
zig-f11b9480192dea44acb92cb9edd7a91c7c73cd2f.zip
allow implicit cast from `S` to `?&const S`
Allow implicit casts from container types to nullable const pointers to said container type. That is: fn f() void { const s = S {}; g(s); // Works. g(&s); // So does this. } fn g(_: ?&const S) void { // Nullable const pointer. } Fixes #731.
Diffstat (limited to 'src')
-rw-r--r--src/ir.cpp17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index b276abff33..e79235830c 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -8817,16 +8817,29 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
// explicit cast from child type of maybe type to maybe type
if (wanted_type->id == TypeTableEntryIdMaybe) {
- if (types_match_const_cast_only(ira, wanted_type->data.maybe.child_type, actual_type, source_node).id == ConstCastResultIdOk) {
+ TypeTableEntry *wanted_child_type = wanted_type->data.maybe.child_type;
+ if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node).id == ConstCastResultIdOk) {
return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);
} else if (actual_type->id == TypeTableEntryIdNumLitInt ||
actual_type->id == TypeTableEntryIdNumLitFloat)
{
- if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.maybe.child_type, true)) {
+ if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) {
return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);
} else {
return ira->codegen->invalid_instruction;
}
+ } else if (wanted_child_type->id == TypeTableEntryIdPointer &&
+ wanted_child_type->data.pointer.is_const &&
+ is_container(actual_type)) {
+ IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_child_type, value);
+ if (type_is_invalid(cast1->value.type))
+ return ira->codegen->invalid_instruction;
+
+ IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);
+ if (type_is_invalid(cast2->value.type))
+ return ira->codegen->invalid_instruction;
+
+ return cast2;
}
}