Skip to content

[pull] master from GaijinEntertainment:master#970

Merged
pull[bot] merged 5 commits into
forksnd:masterfrom
GaijinEntertainment:master
May 8, 2026
Merged

[pull] master from GaijinEntertainment:master#970
pull[bot] merged 5 commits into
forksnd:masterfrom
GaijinEntertainment:master

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 8, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

aleksisch and others added 5 commits May 7, 2026 23:23
Daslang can be used as a dependency in external projects. web can
be counted as an external project. No need to duplicate
CMakeLists.txt.
Added test/language to web. Note, that exceptions is not supported
yet in WASM.

Also added --exclude to dastest framework.
Fixes #2598. Combining daslib/clargs and modules/dasSQLITE/daslib/sqlite_boost
in one module (directly or via require ... public chains) made every
Option<string> ambiguous: [template_structure] cloned an instance struct into
each consuming module via qmacro_template_class, producing N module-aliased
views of the same source decl. Candidate collection treated them as distinct
and emitted "error[30341]: too many matching functions or generics
_::Option<string>" with three identical-looking candidates pointing at
daslib/option.das.

Rather than a typer-side dedupe of candidates by source decl (broader scope,
not gated on this PR), Option and Result now resolve to STRUCTURAL named
tuples. Tuples have no module home; multiple transitive re-exports collapse
to one canonical tTuple TypeDecl regardless of which alias the user lands on.

  [template_structure(T), safe_when_uninitialized] struct template Option ...
  ->
  [template_tuple(T)] struct template Option {
      _has_value : bool = false
      @safe_when_uninitialized _value : T
  }

  Option<T>   -> tuple<_has_value : bool; _value : T>
  Result<T,E> -> tuple<_is_ok : bool; _value : T; _error : E>

* daslib/typemacro_boost.das: new [template_tuple(T...)] structure_macro.
  At apply time it generates a [typemacro_function]; at typemacro-execution
  time the body has two paths:
   - generic: shape-matches a tTuple by argNames + literal-field baseType,
     and feeds template-arg fields into infer_template_types via
     passArgument.argTypes[i].
   - concrete: looks up the source struct via ``typeinfo ast_typedecl(type<X>)``
     (X = the struct's module-scoped alias) and applies templates_boost's
     existing TypeDecl visitor (apply_template + replaceTypeWithTypeDecl) to
     each field. The visitor walks ``T``, ``array<T>``, ``tuple<int; T; E>``,
     etc. uniformly; no apply-time recursion over field shapes is needed.
  Field-level @safe_when_uninitialized propagates: when a source field
  carries the annotation, the corresponding tuple element's TypeDecl gets
  TypeDeclFlags.safeWhenUninitialized. The tuple's recursive unsafeInit
  walks its argTypes, so per-element marking gives the same effect the
  legacy struct-level [safe_when_uninitialized] used to.

* daslib/option.das, daslib/result.das: collapse to near-original struct
  declarations with annotation swap + move_some / move_ok / move_err
  rewrites that drop the typedef RT shorthand in favor of anonymous
  named-tuple construction (new pattern allowed by gen2 grammar).

Compiler-side support for safe-when-uninitialized at TypeDecl granularity:

* TypeDecl::safeWhenUninitialized flag bit + unsafeInit short-circuit. Lets
  a typemacro mark a tuple component (e.g. Option's _value field) safe to
  leave uninitialized even when the underlying T isn't, restoring the
  property the struct-level [safe_when_uninitialized] previously gave
  Option/Result.
* TypeDecl::applyAutoContracts OR-merges the new flag the same way it
  merges ref/constant/temporary, so generic resolution preserves it
  across auto.
* TypeDeclFlags exposes the bit to daslang code.
* InferTypes::preVisit(ExprAssume*) silently dedupes ``assume X : T`` when
  an outer scope already binds X to the same type. Handles the auto-
  injected assume placed at the start of a generic instance body when a
  typemacro-built result type carries an alias the body also references.
* AOT codegen: emit local make-struct destinations without ``const``.
  Aggregate types holding TTuple<> need to be value-init'd at declaration;
  the const qualifier was making C++ reject ``T const x;`` for those shapes.

dasSQLITE adapter rail: is_option_field_type / unwrap_option_payload_type
detect the typeMacro form (during structure_macro apply) and the
post-instantiation tTuple form. The legacy struct-shaped detection drops
out — no in-tree code emits a struct-shaped Option after this PR.

Tests:
* tests/option/test_option_user_struct.das: cross-module Option<UserStruct>.
* tests/option/test_option_unsafe_uninitialized.das: Option<Brittle> where
  Brittle is unsafe-when-uninitialized; covers default<>, none(), some(),
  unwrap_or_default round-trips, and the bare ``var x : Option<Brittle>``
  case which is the only form that hits ast_infer_type.cpp:5040's
  "Uninitialized variable is unsafe" check (verified by removing the
  field annotation locally and observing error[31016]).

Verified: tests/option 205/205 + tests/dasSQLITE 771/771 (interpreted &
AOT); full tests/ tree 7961/7961 interpreted, 7355/7355 AOT. Issue #2598
repro (clargs + sqlite_boost + Option<string>) compiles cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Option<T> / Result<T,E>: structural named-tuple via [template_tuple]
@pull pull Bot locked and limited conversation to collaborators May 8, 2026
@pull pull Bot added the ⤵️ pull label May 8, 2026
@pull pull Bot merged commit 667e8f7 into forksnd:master May 8, 2026
@pull pull Bot had a problem deploying to github-pages May 8, 2026 02:58 Error
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants