compiler: Check optional and slice construction

8841bacd63c519d3fd1d9e14a05338e316d49451a01870e6b652d8110da6dbfc
Alexis Sellier committed ago 1 parent 22ef7605
lib/std/lang/lower.rad +12 -8
4530 4530
/// Wrap a value in an optional type.
4531 4531
///
4532 4532
/// For optional pointers (`?*T`), the value is returned as-is since pointers
4533 4533
/// use zero to represent `nil`. For other optionals, builds a tagged aggregate.
4534 4534
/// with the tag set to `1`, and the value as payload.
4535 -
unsafe fn wrapInOptional 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, val: il::Val, optType: resolver::Type) -> il::Val throws (LowerError) where 'arena: 'phase, 'phase: 'function {
4535 +
fn wrapInOptional 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, val: il::Val, optType: resolver::Type) -> il::Val throws (LowerError) where 'arena: 'phase, 'phase: 'function {
4536 4536
    let case resolver::Type::Optional(inner) = optType else {
4537 4537
        throw LowerError::ExpectedOptional;
4538 4538
    };
4539 4539
    // Null-pointer-optimized (NPO) types are used as-is -- valid values are never null.
4540 4540
    if resolver::isNullableType(*inner) {
4541 4541
        return val;
4542 4542
    }
4543 -
    let layout = resolver::getTypeLayout(optType);
4544 -
    let valOffset = resolver::getOptionalValOffset(resolver::getTypeLayout(*inner)) as i32;
4543 +
    unsafe {
4544 +
        let layout = resolver::getTypeLayout(optType);
4545 +
        let valOffset = resolver::getOptionalValOffset(resolver::getTypeLayout(*inner)) as i32;
4545 4546
4546 -
    return try buildTagged(self, layout, 1, val, *inner, 1, valOffset);
4547 +
        return try buildTagged(self, layout, 1, val, *inner, 1, valOffset);
4548 +
    }
4547 4549
}
4548 4550
4549 4551
/// Build a `nil` value for an optional type.
4550 4552
///
4551 4553
/// For optional pointers (`?*T`), returns an immediate `0` (null pointer).
4552 4554
/// For other optionals, builds a tagged aggregate with tag set to `0` (absent).
4553 -
unsafe fn buildNilOptional 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, optType: resolver::Type) -> il::Val throws (LowerError) where 'arena: 'phase, 'phase: 'function {
4555 +
fn buildNilOptional 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, optType: resolver::Type) -> il::Val throws (LowerError) where 'arena: 'phase, 'phase: 'function {
4554 4556
    let case resolver::Type::Optional(inner) = optType
4555 4557
        else throw LowerError::ExpectedOptional;
4556 4558
    if let case resolver::Type::Pointer { .. } = *inner {
4557 4559
        return il::Val::Imm(0);
4558 4560
    }
4559 4561
    if let case resolver::Type::Slice { item, mutable, .. } = *inner {
4560 4562
        return try buildSliceValue(
4561 4563
            self, item, mutable, il::Val::Imm(0), il::Val::Imm(0), il::Val::Imm(0)
4562 4564
        );
4563 4565
    }
4564 -
    let valOffset = resolver::getOptionalValOffset(resolver::getTypeLayout(*inner)) as i32;
4565 -
    return try buildTagged(self, resolver::getTypeLayout(optType), 0, nil, *inner, 1, valOffset);
4566 +
    unsafe {
4567 +
        let valOffset = resolver::getOptionalValOffset(resolver::getTypeLayout(*inner)) as i32;
4568 +
        return try buildTagged(self, resolver::getTypeLayout(optType), 0, nil, *inner, 1, valOffset);
4569 +
    }
4566 4570
}
4567 4571
4568 4572
/// Build a result value for throwing functions.
4569 4573
unsafe fn buildResult 'arena 'phase 'function (
4570 4574
    self: &mut FnLowerer 'arena 'phase 'function,
4578 4582
    );
4579 4583
    return try buildTagged(self, layout, tag, payload, payloadType, resolver::PTR_SIZE as i32, RESULT_VAL_OFFSET);
4580 4584
}
4581 4585
4582 4586
/// Build a slice aggregate from a data pointer, length and capacity.
4583 -
unsafe fn buildSliceValue 'arena 'phase 'function (
4587 +
fn buildSliceValue 'arena 'phase 'function (
4584 4588
    self: &mut FnLowerer 'arena 'phase 'function,
4585 4589
    elemTy: *resolver::Type,
4586 4590
    mutable: bool,
4587 4591
    ptrVal: il::Val,
4588 4592
    lenVal: il::Val,