Skip to content

Optional-chaining (?.) result does not match a written Option[T] annotation #307

@ehartford

Description

@ehartford

Summary

The result of ?. optional chaining type-checks and compares correctly when its type is inferred, but does not unify with an explicitly written Option[T] annotation — type mismatch in binding. The chained Option appears to be a structurally-equal-but-distinct type from the canonical Option[T].

Reproduction

type A { city: Option[str] }
type P { address: Option[A] }

// OK — inferred, and compares to Some(...)
fn inferred(p: P):
    let c = p.address?.city
    assert(c == Some("x"))

// ERR — same expression, with the annotation it should have
fn annotated(p: P):
    let c: Option[str] = p.address?.city   // error: type mismatch in binding
    let _ = c
error: type mismatch in binding
 --> x.w:9:5
    let c: Option[str] = p.address?.city
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Notes

  • The §10.3 spec test (test/spec/spec_ss10_3_optional_chaining.w) passes because it uses the inferred form (let city = profile.address?.city; assert(city == Some(...))). Adding the matching annotation breaks it.
  • This is the same shape as the canonicalization gap seen with compiler-backed HashMap.get returning Option[enum] vs a written Option[enum]: the synthesized Option type isn't the same TypeId as the annotated one.
  • A related observation: with an Option-typed head (find_user(id)?.address?.city where find_user -> Option[User]) the result is mis-typed entirely (a later let _ = even warns about cancelling a Task) — likely the same non-canonical-Option root cause, worth checking together.

Found while updating docs/with-idiomatic-guide.md.

Env: with v0.13.1-g7104bb5d7 (origin/main 9865cbb), darwin-aarch64.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    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