Skip to content

Require unsafe for raw-pointer-to-safe-reference/view conversions #364

@ehartford

Description

@ehartford

Summary

The spec now adopts the §16.11 operation-specific unsafe boundary: raw pointer arithmetic/comparison are safe address computations, but converting a raw pointer into a safe memory abstraction is unsafe because it asserts validity, bounds, alignment, lifetime, initialization, ownership, and provenance.

Currently p as &T typechecks in safe code.

Repro

fn main:
    var value = 1
    let p = (&raw mut value) as *mut i32
    let r = p as &i32      // should require unsafe
    let _ = r

Observed with ./out/bin/with check: this currently reports ok.

Expected

The cast should be rejected outside an unsafe context with a directional diagnostic, for example:

raw pointer to reference conversion requires unsafe context

The same boundary should apply to raw-pointer-to-slice/view conversion or any equivalent conversion that creates a safe abstraction from raw memory.

Root cause / 5 Whys

  1. Why does the unsafe conversion compile? NK_CAST resolves the source and target types, then returns the target type without requiring unsafe for pointer-to-reference conversions.
  2. Why is the cast considered valid? types_compatible currently treats pointer/reference combinations as structurally compatible when pointee types match.
  3. Why is that unsafe? A safe reference/view carries trusted facts: validity, bounds, alignment, initialization, liveness, ownership, lifetime, and possibly provenance.
  4. Why can't the compiler infer those facts from p as &T? A raw pointer value carries none of those guarantees merely by existing or being arithmetically computed.
  5. Root cause: the checker conflates pointer/reference representational compatibility with the unsafe assertion needed to promote raw memory into a safe abstraction.

Code pointers

  • src/SemaCheck.w:2973 handles NK_CAST.
  • src/Sema.w:3177 and src/Sema.w:3193 accept pointer/reference compatibility.
  • src/SemaCheck.w:7647 already requires unsafe for transmute; raw-to-safe conversion needs the same style of boundary check.
  • Existing negative fixtures cover raw dereference/indexing (err_issue145_raw_deref_requires_unsafe.w, err_issue146_raw_ptr_index_requires_unsafe.w), but not raw-to-reference conversion.

Acceptance criteria

  • p as &T and p as &mut T / mutable-reference equivalent require unsafe when p is a raw pointer.
  • Raw pointer to slice/view/safe memory abstraction conversion requires unsafe at the conversion site.
  • Raw pointer arithmetic, null checks, equality checks, and raw address comparison remain safe.
  • Safe pointer-to-pointer casts and pointer/integer casts remain governed by their existing safe rules unless they create a safe memory abstraction.
  • Add compile-error fixtures for safe raw-pointer-to-reference/view conversion.
  • Add positive fixtures showing the same conversions compile inside unsafe.
  • with build, with build :fixpoint, with build :test, and with build :test-green pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions