Перейти к содержимому
Топаз6.0 · До релиза
Загрузка →

Поиск в документации

Спецификация 6.0

Выберите результат стрелками и нажмите Enter, чтобы открыть его.

Введите имя API, номер диагностики, правило или тему проекта.

    Язык · 4 главы · 21 правило

    Связывания и область действия

    Defines how names are introduced, resolved, and reassigned.

    Scope and status

    Ссылка

    Use this page to declare bindings and understand name lookup, assignment, and lexical capture.

    Types covers compatibility and shared inference. Functions and generics covers calls and generic specialization. Pattern forms, module lookup, and protocol resolution belong to their respective chapters.

    Declaration syntax

    Ссылка
    EBNF
    1. NamedLet = "let" "mut"? Identifier (":" Type)? "=" Expression ;
    2. Const = "const" Identifier (":" Type)? "=" Expression ;
    3. Assignment = AssignmentTarget "=" Expression ;
    4. AssignmentTarget = Identifier | MemberAccess | IndexAccess ;

    This transcribed excerpt shows named declarations and plain assignment. Pattern forms, compound operators, and statement boundaries have separate grammar productions.

    Declaration source observations

    Ссылка
    Правилоtopaz.rule.bindings-and-scope.declaration-forms

    Binding declaration forms

    Each declaration requires an initializer after = and permits a type annotation. A named binding accepts at most one annotation, including an exported binding. Repeating the annotation produces TPZ2001 during parsing.

    DeclarationBinding form
    letA pattern
    let mutA single name
    constA single name

    Причина

    An initializer gives every binding a value. One type annotation supplies one expectation without a second spelling or a competing annotation for the same name.

    Правилоtopaz.rule.bindings-and-scope.declaration-mutability

    Binding mutability

    DeclarationBinding mutability
    letImmutable
    let mutMutable
    constImmutable

    Причина

    Reassignment is an explicit choice in the declaration. Immutable bindings let readers rely on one assigned value.

    Правилоtopaz.rule.bindings-and-scope.const-literals

    Literal const initializers

    Integer literals and untagged string literals without interpolation satisfy the constant-expression requirement for const initializers.

    Причина

    A literal supplies its value without consulting runtime state, so it can be used wherever a constant expression is required.

    Правилоtopaz.rule.bindings-and-scope.const-runtime-reference

    Const references to let bindings

    A const initializer must be a constant expression. Referencing an ordinary let or let mut binding is rejected with TPZ5001.

    Причина

    An immutable runtime binding can still depend on runtime computation. Rejecting such references keeps constant-expression admission independent of runtime state.

    Правилоtopaz.rule.bindings-and-scope.none-binding-name

    Reserved None binding name

    None cannot be a binding name. This includes let mut, const, typed binding patterns, and bare untyped patterns. The parser reports TPZ2012. Write None() for the Option constructor in patterns and values.

    Причина

    Reserving None keeps absence recognizable in expressions and patterns. A local name cannot silently replace the Option constructor.

    Правилоtopaz.rule.bindings-pending.constant-evaluation

    Constant expressions and retained values

    A const initializer must pass ordinary name and type checking and the constant-expression check. Admitted forms include scalar and Length literals, None(), untagged strings with constant interpolations, available constant bindings, function values, parentheses, unary expressions, binary expressions other than in, arrays without spread, and record literals whose fields are constant expressions. A reference to a let binding, an ordinary function call, or a later constant in the same module is rejected. Const makes the binding immutable. Its data follows collection value semantics. Grouping a callee preserves its operation and receiver. The grouping does not change whether the call is a constant expression.

    The numeric call forms are int.and, int.or, int.xor, and int.shift with one constant integer operand, and float.trunc, float.floor, float.ceil, and float.round with no arguments and a constant float receiver. These calls take no explicit type arguments or spreads. Integer operands are supplied positionally. Integer and float arithmetic expressions may supply their receivers.

    Compiler-recognized std.typeset.fromScaledPoints and fromMilliPoints calls, Length conversion methods toPt, toMm, toCm, toIn and toScaledPoints, Pt.toMilliPoints, and Em.resolve admit constant operands. The std.typeset constructor recognition requires the generated standard module. Normal type and argument checks still apply. The implementation issue below preserves the permitted function-value expectation. Initialization-pass ordering is not a new language timing guarantee.

    Причина

    A constant must not depend on runtime state. Grouping a callee preserves its operation and receiver, so it must preserve the same constant-expression decision.

    Assignment source observations

    Ссылка
    Правилоtopaz.rule.bindings-and-scope.collection-value-semantics

    Collection values

    Since 6.0.0, Array, Map, Set, and ByteBuffer are values. Assignment, argument passing, return, and immutable capture each produce an independent value. Storing a value in a record field, collection element, or Map key or value does the same. Changing one value leaves the others unchanged.

    The rule applies recursively inside records, enum payloads, Option, and Result. ByteBuffer contains data without host state and follows the same rule.

    A write requires one let mut root binding, including writes through nested fields, indices, and collection operations. An immutable binding's data cannot change through an alias. The immutable assignment rule governs the write path. A function cannot change a caller's collection through a parameter. Bind a mutable local and return the changed value when the caller needs it.

    An implementation may share storage and copy when a write occurs. A program cannot observe this storage sharing. The rule makes no promise about allocation, time, or space costs.

    Shared handles represent host resources. File retains its shared cursor and closed state. A mutable capture shares one variable. A closure's write to that variable is visible outside the closure. A value assigned to another variable before the write remains unchanged.

    See immutable assignment, capture observation, parameter bindings, and collection keys. The existing File cursor example and closed handle example show the resource exception.

    Причина

    Each intent has one representation. Data uses values and host resources use handles. Independent values prevent hidden changes, so results are reproducible and easy to verify. Concurrent work on separate collection values has no data race through shared collection storage. Collections map directly to value representations such as Rust Vec and HashMap.

    Правилоtopaz.rule.bindings-and-scope.assignment-forms

    Assignment target syntax

    An assignment target must be an identifier, member access, or index access. Other expression shapes produce TPZ2003 during parsing. The target also undergoes receiver and mutability checks.

    Причина

    Assignment must identify a location that can receive a value. A temporary result has no binding or element to update.

    Правилоtopaz.rule.bindings-and-scope.immutable-assignment

    Assignment requires a mutable root

    Direct replacement of an imported binding is rejected during resolution under the import assignment rule. After resolution succeeds, assignment to an immutable binding, or to a member or index rooted in that binding, is rejected with TPZ5003.

    Причина

    Mutability follows the root binding through field and index access. Adding an access step must not bypass the declaration's mutation rule.

    Правилоtopaz.rule.bindings-and-scope.assignment-type

    Expected type of assignment

    For =, the target type is the expected type of the right-hand expression.

    Причина

    The destination already determines which values an assignment can store. Reusing that type gives empty or generic values the context they need.

    Правилоtopaz.rule.bindings-and-scope.optional-assignment

    Assignment through optional access

    A member or index assignment target whose receiver chain contains optional access ?. is rejected during checking with TPZ5001.

    Причина

    An optional receiver can be absent, leaving no location to update. An explicit branch makes the skipped update and value evaluation visible.

    Правилоtopaz.rule.bindings-and-scope.map-assignment

    Assignment through Map indexing

    Assignment through a Map index is rejected with TPZ5001. Use the Map mutation API to update that binding's value under collection value semantics.

    Причина

    Map insertion can add a key as well as replace a value. A named mutation operation makes that behavior explicit without another update spelling.

    Scope and capture source observations

    Ссылка
    Правилоtopaz.rule.bindings-and-scope.lexical-lookup

    Lexical name lookup

    Local name lookup searches active scopes from the innermost outward and selects the first matching binding. Value and type namespaces are searched separately.

    Причина

    Lexical nesting determines what a name means without depending on the caller. Separate namespaces keep value lookup from selecting a type declaration.

    Правилоtopaz.rule.bindings-and-scope.block-scope

    Nested block scope

    A nested block introduces a scope. After an inner binding is declared, later references inside the block resolve to it instead of an outer binding of the same name. References outside that block continue to resolve to the outer binding.

    Причина

    A block bounds the visibility of local names. Temporary names inside it cannot replace the bindings used by surrounding code.

    Правилоtopaz.rule.bindings-and-scope.local-initializer-scope

    Local initializer scope

    Local let, const names become visible after their initializers have been resolved. An existing outer binding of the same name remains visible in the initializer.

    Причина

    The initializer can use an existing outer value while computing its replacement. The new name becomes usable after that value exists.

    Правилоtopaz.rule.bindings-and-scope.unbound-name

    Unbound value names

    An ordinary value identifier with no binding or built-in definition is rejected with TPZ5002. Namespace heads follow the module lookup rules.

    Причина

    Every ordinary reference needs a declaration that determines its value. Static rejection prevents execution with an unspecified binding.

    Правилоtopaz.rule.bindings-and-scope.top-level-direct-forward-read

    Direct top-level forward reads

    A top-level let initializer that directly reads a later let binding in the same module is rejected with TPZ3018 during resolution, for both entry and imported files. Declaration order is the statement order in that module.

    Причина

    A declaration cannot read a runtime value that has not been initialized. Resolving direct reads before execution catches this mistake with the same TPZ3018 identity in entry and imported files. Local unbound-name errors and delayed runtime reads retain their separate TPZ5002 contract.

    Правилоtopaz.rule.bindings-and-scope.lexical-capture

    Lexical capture identity

    A function or lambda reference to an outer lexical binding in the same module resolves to that binding’s original declaration.

    Причина

    A closure's references keep the meaning they had where it was defined. Calling it from a different scope must not retarget those names.

    Правилоtopaz.rule.bindings-pending.capture-observation

    Values observed by existing and escaping closures

    Closures that capture the same mutable binding observe its later assignments, including assignments made by another closure. An immutable capture retains its assigned value and cannot be rebound inside the closure. Collection values follow value semantics. Captured values and shared bindings remain available after the creating function returns while a closure retains them.

    Причина

    A mutable captured binding represents one shared variable. Retaining captured storage while closures exist prevents references from outliving their values.

    Правилоtopaz.rule.bindings-pending.initialization-order

    Initialization through branches, calls, and closures

    Module-level let bindings become ready after their initializers complete, and function bindings become ready at their declaration position. A direct initializer read of the same or a later runtime binding is rejected with TPZ3018 during resolution in entry and imported files alike. The direct check follows an if or while condition, a match scrutinee, a for iterator, and the first comprehension source. It does not enter function, lambda, branch, arm, or loop bodies. Short-circuit right operands and optional-call arguments are delayed as well. A delayed reference reads the binding when execution reaches it. Reading before initialization faults with TPZ5002; reading after initialization returns the current value. Merely storing a closure does not evaluate its body.

    Причина

    Module initialization can perform effects, so source order determines when runtime values become available. Delayed code must check the value when it actually executes.

    Правилоtopaz.rule.bindings-pending.same-scope-redeclarations

    Redeclaration and nested shadowing

    A module-level name may be declared once. Let, const, function, type, and imported declarations participate in the same module name table, and a second declaration is rejected with TPZ3008. Reusing a name in a nested scope is shadowing. A repeated local const is rejected with TPZ5008. The same local scope must also reject a second let or let mut name; the current let pattern path bypasses the checker guard, which is recorded as an implementation limitation. The local let regression retains TPZ5008 as its intended rejection contract.

    Причина

    A name should identify one declaration within a scope. Rejecting duplicates prevents silent replacement, while nested scopes make shadowing explicit.

    Examples and expected results

    Ссылка

    Each example is a complete example.tpz file. The expected success or rejection is independent of future observed output. All examples remain Pending. A source-backed expectation is not an executed result. Negative examples specify the intended cause and phase; their exact diagnostic locations remain unmeasured.

    Immutable, mutable, and constant bindings

    Ссылка
    example.tpzImmutable, mutable, and constant bindingsОткрыть песочницу →
    1. import std.io
    2. let start: int = 1
    3. let mut count: int = start
    4. count = 2
    5. const label = "Topaz"
    6. io.writeLine("{label}:{start}:{count}")
    Зафиксированный выводКод завершения 0
    Topaz:1:2
    
    $ topaz run example.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. Topaz:1:2
    Наблюдаемые утверждения · Пройдено · 5.21.3

    Код завершения 0.

    Наблюдаемый стандартный вывод
    1. Topaz:1:2

    Нет вывода ошибок.

    • Пройдено · expected 0; observed 0
    • Пройдено · stdout matches the authored expectation
    • Пройдено · stderr matches the authored expectation
    • Пройдено · stdout matches the authored expectation
    • Пройдено · stdout matches the authored expectation
    • Пройдено · stdout matches the authored expectation
    • Пройдено · stdout matches the authored expectation

    An immutable binding cannot be reassigned

    Ссылка
    example.tpzAn immutable binding cannot be reassignedОткрыть песочницу →
    1. let count: int = 1
    2. count = 2
    Зафиксированный выводКод завершения 1
    Нет стандартного вывода.
    error[TPZ5003]: `count` is immutable; declare it with `let mut`
     --> example.tpz:2:1
      |
    2 | count = 2
      | ^^^^^
    
    example.tpz: 1 type diagnostic
    
    $ topaz check example.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    • TPZ5003 →

      bindings-assignment-to-immutable at example.tpz:2:1

    Наблюдаемые утверждения · Пройдено · 5.21.3

    Код завершения 1.

    Нет стандартного вывода.

    Наблюдаемый вывод ошибок
    1. error[TPZ5003]: `count` is immutable; declare it with `let mut`
    2. --> example.tpz:2:1
    3. |
    4. 2 | count = 2
    5. | ^^^^^
    6. example.tpz: 1 type diagnostic
    • Пройдено · expected nonzero; observed 1
    • Пройдено · stdout matches the authored expectation
    • Пройдено · checking TPZ5003; cause bindings-assignment-to-immutable; primary location asserted; additional diagnostics allow
    • Пройдено · checking TPZ5003; cause bindings-assignment-to-immutable; primary location asserted; additional diagnostics allow

    An ordinary let reference is not a const initializer

    Ссылка
    example.tpzAn ordinary let reference is not a const initializerОткрыть песочницу →
    1. let source: int = 1
    2. const frozen: int = source
    Зафиксированный выводКод завершения 1
    Нет стандартного вывода.
    error[TPZ5001]: `const` initializers must be constant expressions (§4)
     --> example.tpz:2:21
      |
    2 | const frozen: int = source
      |                     ^^^^^^
    
    example.tpz: 1 type diagnostic
    
    $ topaz check example.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    • TPZ5001 →

      bindings-const-runtime-reference at example.tpz:2:21

    Наблюдаемые утверждения · Пройдено · 5.21.3

    Код завершения 1.

    Нет стандартного вывода.

    Наблюдаемый вывод ошибок
    1. error[TPZ5001]: `const` initializers must be constant expressions (§4)
    2. --> example.tpz:2:21
    3. |
    4. 2 | const frozen: int = source
    5. | ^^^^^^
    6. example.tpz: 1 type diagnostic
    • Пройдено · expected nonzero; observed 1
    • Пройдено · stdout matches the authored expectation
    • Пройдено · checking TPZ5001; cause bindings-const-runtime-reference; primary location asserted; additional diagnostics allow

    None cannot name a mutable binding

    Ссылка
    example.tpzNone cannot name a mutable bindingОткрыть песочницу →
    1. let mut None = 1
    Зафиксированный выводКод завершения 1
    Нет стандартного вывода.
    error[TPZ2012]: `None` is the Option constructor (§22.1) and cannot be a binding name
     --> example.tpz:1:9
      |
    1 | let mut None = 1
      |         ^^^^
    
    example.tpz: 1 diagnostic
    
    $ topaz check example.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения parse. Ненулевой код завершения.

    Наблюдаемые утверждения · Пройдено · 5.21.3

    Код завершения 1.

    Нет стандартного вывода.

    Наблюдаемый вывод ошибок
    1. error[TPZ2012]: `None` is the Option constructor (§22.1) and cannot be a binding name
    2. --> example.tpz:1:9
    3. |
    4. 1 | let mut None = 1
    5. | ^^^^
    6. example.tpz: 1 diagnostic
    • Пройдено · expected nonzero; observed 1
    • Пройдено · stdout matches the authored expectation
    • Пройдено · checking TPZ2012; cause bindings-none-name; primary location asserted; additional diagnostics allow

    A nested binding shadows the outer one

    Ссылка
    example.tpzA nested binding shadows the outer oneОткрыть песочницу →
    1. import std.io
    2. let value: int = 1
    3. let nested: string = {
    4. let value: string = "inner"
    5. value
    6. }
    7. let original: int = value
    8. io.writeLine("{nested}:{original}")
    Зафиксированный выводКод завершения 0
    inner:1
    
    $ topaz run example.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. inner:1
    Наблюдаемые утверждения · Пройдено · 5.21.3

    Код завершения 0.

    Наблюдаемый стандартный вывод
    1. inner:1

    Нет вывода ошибок.

    • Пройдено · expected 0; observed 0
    • Пройдено · stdout matches the authored expectation
    • Пройдено · stderr matches the authored expectation
    • Пройдено · stdout matches the authored expectation

    An ordinary unbound name is rejected

    Ссылка
    example.tpzAn ordinary unbound name is rejectedОткрыть песочницу →
    1. let copied: int = missing
    Зафиксированный выводКод завершения 1
    Нет стандартного вывода.
    error[TPZ5002]: `missing` is not bound
     --> example.tpz:1:19
      |
    1 | let copied: int = missing
      |                   ^^^^^^^
    
    example.tpz: 1 type diagnostic
    
    $ topaz check example.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    Наблюдаемые утверждения · Пройдено · 5.21.3

    Код завершения 1.

    Нет стандартного вывода.

    Наблюдаемый вывод ошибок
    1. error[TPZ5002]: `missing` is not bound
    2. --> example.tpz:1:19
    3. |
    4. 1 | let copied: int = missing
    5. | ^^^^^^^
    6. example.tpz: 1 type diagnostic
    • Пройдено · expected nonzero; observed 1
    • Пройдено · stdout matches the authored expectation
    • Пройдено · checking TPZ5002; cause bindings-unbound-read; primary location asserted; additional diagnostics allow

    A later top-level let is unavailable to a direct initializer

    Ссылка
    example.tpzA later top-level let is unavailable to a direct initializerОткрыть песочницу →
    1. let before: int = after
    2. let after: int = 1
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check example.tpz --compiler self · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения resolve. Ненулевой код завершения.

    • TPZ3018 →

      module-initializer-not-ready at example.tpz:1:19

    The direct module initializer uses the same TPZ3018 resolve contract in entry and imported files. Current SELF rejects this entry source with TPZ5002; the existing receipt remains historical evidence for that earlier identity. The expected rejection and location are retained, and only the diagnostic assertion is limited.

    A lambda refers to an outer binding

    Ссылка
    example.tpzA lambda refers to an outer bindingОткрыть песочницу →
    1. import std.io
    2. let anchor: int = 7
    3. let reader: (int) -> int = (value) => anchor
    4. let observed: int = {
    5. let anchor: int = 99
    6. reader(0)
    7. }
    8. io.writeLine("{observed}")
    Зафиксированный выводКод завершения 0
    7
    
    $ topaz run example.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 7
    Наблюдаемые утверждения · Пройдено · 5.21.3

    Код завершения 0.

    Наблюдаемый стандартный вывод
    1. 7

    Нет вывода ошибок.

    • Пройдено · expected 0; observed 0
    • Пройдено · stdout matches the authored expectation
    • Пройдено · stderr matches the authored expectation

    Two escaping closures share one mutable binding

    Ссылка
    example.tpzTwo escaping closures share one mutable binding
    1. import std.io
    2. function makeCounters() -> { advance: () -> int, read: () -> int } {
    3. let mut count: int = 0
    4. let advance: () -> int = () => {
    5. count += 1
    6. count
    7. }
    8. let read: () -> int = () => count
    9. count = 4
    10. { advance: advance, read: read }
    11. }
    12. let counters = makeCounters()
    13. io.writeLine("{counters.read()}:{counters.advance()}:{counters.read()}")
    Ожидаемый выводКод завершения 0
    4:5:5
    
    $ topaz run example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 4:5:5

    Immutable captures retain independent collection values

    Ссылка
    example.tpzImmutable captures retain independent collection values
    1. import std.io
    2. function makeReader() -> () -> string {
    3. let mut current: int = 1
    4. let snapshot: int = current
    5. let items: Array<int> = [10]
    6. let mut alias: Array<int> = items
    7. let read: () -> string = () => "{current}:{snapshot}:{items[0]}"
    8. current = 2
    9. alias[0] = 30
    10. read
    11. }
    12. let read = makeReader()
    13. io.writeLine(read())
    Ожидаемый выводКод завершения 0
    2:1:10
    
    $ topaz run example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 2:1:10

    A closure cannot reassign an immutable capture

    Ссылка
    example.tpzA closure cannot reassign an immutable captureОткрыть песочницу →
    1. function makeReader() -> () -> int {
    2. let count: int = 1
    3. () => {
    4. count = 2
    5. count
    6. }
    7. }
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    • TPZ5003 →

      bindings-assignment-to-immutable at example.tpz:4:9

    Call a stored closure after its later binding initializes

    Ссылка
    example.tpzCall a stored closure after its later binding initializes
    1. import std.io
    2. let read: () -> int = () => later
    3. let later: int = 7
    4. io.writeLine("{read()}")
    Ожидаемый выводКод завершения 0
    7
    
    $ topaz run example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 7

    A skipped branch does not read a later binding

    Ссылка
    example.tpzA skipped branch does not read a later binding
    1. import std.io
    2. let chosen: int = if (false) { after } else { 2 }
    3. let after: int = 7
    4. io.writeLine("{chosen}:{after}")
    Ожидаемый выводКод завершения 0
    2:7
    
    $ topaz run example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 2:7

    The condition is an immediate initializer read

    Ссылка
    example.tpzThe condition is an immediate initializer readОткрыть песочницу →
    1. let chosen: int = if (after) { 1 } else { 2 }
    2. let after: bool = true
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения resolve. Ненулевой код завершения.

    • TPZ3018 →

      module-initializer-not-ready at example.tpz:1:23

    The direct module initializer uses the same TPZ3018 resolve contract in entry and imported files. Current SELF rejects this entry source with TPZ5002; the existing receipt remains historical evidence for that earlier identity. The expected rejection and location are retained, and only the diagnostic assertion is limited.

    An executed branch faults before a later binding initializes

    Ссылка
    example.tpzAn executed branch faults before a later binding initializes
    1. let chosen: int = if (true) { after } else { 0 }
    2. let after: int = 7
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz run example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    • TPZ5002 →

      bindings-direct-forward-read at example.tpz:1:31

    An inner scope may reuse an outer name

    Ссылка
    example.tpzAn inner scope may reuse an outer name
    1. import std.io
    2. let value: int = 1
    3. let inner: int = {
    4. let value: int = 2
    5. value
    6. }
    7. io.writeLine("{value}:{inner}")
    Ожидаемый выводКод завершения 0
    1:2
    
    $ topaz run example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 1:2

    Module declarations cannot reuse an existing name

    Ссылка
    example.tpzModule declarations cannot reuse an existing nameОткрыть песочницу →
    1. let value: int = 1
    2. const value: int = 2
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения resolve. Ненулевой код завершения.

    • TPZ3008 →

      bindings-same-scope-redeclaration at example.tpz:2:7

    A local let duplicate retains the intended static rejection

    Ссылка
    example.tpzA local let duplicate retains the intended static rejectionОткрыть песочницу →
    1. function invalid() -> int {
    2. let value: int = 1
    3. let value: int = 2
    4. value
    5. }
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    • TPZ5008 →

      bindings-local-same-scope-redeclaration at example.tpz:3:9

    Constant expressions retain independent collection values

    Ссылка
    example.tpzConstant expressions retain independent collection values
    1. import std.io
    2. const base: int = 2
    3. const bits: int = base.shift(1).or(1)
    4. const rounded: int = (2.2).ceil()
    5. const data = { label: "value-{base}", values: [base, bits] }
    6. let mut alias: Array<int> = data.values
    7. alias[0] = 9
    8. io.writeLine("{data.label}:{bits}:{rounded}:{data.values[0]}")
    Ожидаемый выводКод завершения 0
    value-2:5:3:2
    
    $ topaz run example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. value-2:5:3:2

    A constant cannot read a later same-module constant

    Ссылка
    example.tpzA constant cannot read a later same-module constantОткрыть песочницу →
    1. const before: int = after
    2. const after: int = 7
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    • TPZ5002 →

      bindings-direct-forward-read at example.tpz:1:21

    A permitted named function value remains the expected constant value

    Ссылка
    example.tpzA permitted named function value remains the expected constant value
    1. import std.io
    2. function answer() -> int { 7 }
    3. const saved: () -> int = answer
    4. io.writeLine("{saved()}")
    Ожидаемый выводКод завершения 0
    7
    
    $ topaz run example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 7

    Store the function value after its declaration executes

    Ссылка
    example.tpzStore the function value after its declaration executes
    1. import std.io
    2. function answer() -> int { 7 }
    3. let saved: () -> int = answer
    4. io.writeLine("{saved()}")
    Ожидаемый выводКод завершения 0
    7
    
    $ topaz run example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 7

    The local const path checks duplicate names

    Ссылка
    example.tpzThe local const path checks duplicate namesОткрыть песочницу →
    1. function invalid() -> int {
    2. const value: int = 1
    3. const value: int = 2
    4. value
    5. }
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    • TPZ5008 →

      bindings-local-same-scope-redeclaration at example.tpz:3:11

    Repeat a let annotation

    Ссылка
    example.tpzRepeat a let annotationОткрыть песочницу →
    1. let answer: int: int = 1
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check example.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения parse. Ненулевой код завершения.

    • TPZ2001 →

      bindings-duplicate-type-annotation at example.tpz:1:16

    Repeat an exported let annotation

    Ссылка
    example.tpzRepeat an exported let annotationОткрыть песочницу →
    1. export let answer: int: int = 1
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check example.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения parse. Ненулевой код завершения.

    • TPZ2001 →

      bindings-duplicate-type-annotation at example.tpz:1:23

    Repeat a mutable binding annotation

    Ссылка
    example.tpzRepeat a mutable binding annotationОткрыть песочницу →
    1. let mut answer: int: int = 1
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check example.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения parse. Ненулевой код завершения.

    • TPZ2001 →

      bindings-duplicate-type-annotation at example.tpz:1:20

    Repeat a constant annotation

    Ссылка
    example.tpzRepeat a constant annotationОткрыть песочницу →
    1. const answer: int: int = 1
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check example.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения parse. Ненулевой код завершения.

    • TPZ2001 →

      bindings-duplicate-type-annotation at example.tpz:1:18

    Annotate each binding once

    Ссылка
    example.tpzAnnotate each binding onceОткрыть песочницу →
    1. let local: int = 1
    2. export let published: int = local
    3. let mut count: int = local
    4. const label: string = "Topaz"
    5. export const publishedLabel: string = label
    Ожидаемый выводКод завершения 0
    Нет стандартного вывода.
    $ topaz check example.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Проверка принимает программу. Код завершения 0.

    Group admitted numeric callees

    Ссылка
    example.tpzGroup admitted numeric calleesОткрыть песочницу →
    1. const bits: int = ((5).and)(3)
    2. const rounded: int = ((2.2).ceil)()
    Ожидаемый выводКод завершения 0
    Нет стандартного вывода.
    $ topaz check example.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Проверка принимает программу. Код завершения 0.

    Group admitted length callees

    Ссылка
    example.tpzGroup admitted length calleesОткрыть песочницу →
    1. import std.typeset
    2. const physical: Length<Pt> = ((1in).toPt)()
    3. const relative: Length<Pt> = ((2em).resolve)(12pt)
    Ожидаемый выводКод завершения 0
    Нет стандартного вывода.
    $ topaz check example.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Проверка принимает программу. Код завершения 0.

    Use admitted calls and a grouped length constructor

    Ссылка
    example.tpzUse admitted calls and a grouped length constructorОткрыть песочницу →
    1. import std.typeset
    2. const bits: int = (5).and(3)
    3. const rounded: int = (2.2).ceil()
    4. const physical: Length<Pt> = (1in).toPt()
    5. const relative: Length<Pt> = (2em).resolve(12pt)
    6. const constructed: Length<Pt> = (typeset.fromMilliPoints)(1000)
    Ожидаемый выводКод завершения 0
    Нет стандартного вывода.
    $ topaz check example.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Проверка принимает программу. Код завершения 0.

    An ordinary call remains a runtime computation

    Ссылка
    example.tpzAn ordinary call remains a runtime computationОткрыть песочницу →
    1. function answer() -> int { 3 }
    2. const direct: int = answer()
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check example.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    • TPZ5001 →

      bindings-const-ordinary-call at example.tpz:2:21

    Grouping does not make an ordinary call constant

    Ссылка
    example.tpzGrouping does not make an ordinary call constantОткрыть песочницу →
    1. function answer() -> int { 3 }
    2. const grouped: int = (answer)()
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check example.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    • TPZ5001 →

      bindings-const-ordinary-call at example.tpz:2:22

    Assignment keeps array values independent

    Ссылка
    example.tpzAssignment keeps array values independent
    1. import std.io
    2. let a = [1, 2]
    3. let mut b = a
    4. b.push(3)
    5. io.writeLine("{a.length}:{b.length}")
    Ожидаемый выводКод завершения 0
    2:3
    
    $ topaz run example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 2:3

    Return a changed local value from a function

    Ссылка
    example.tpzReturn a changed local value from a function
    1. import std.io
    2. function appended(values: Array<int>) -> Array<int> {
    3. let mut local = values
    4. local.push(3)
    5. local
    6. }
    7. let items = [1, 2]
    8. let changed = appended(items)
    9. io.writeLine("{items.length}:{changed.length}")
    Ожидаемый выводКод завершения 0
    2:3
    
    $ topaz run example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 2:3

    A saved record keeps its collection field

    Ссылка
    example.tpzA saved record keeps its collection field
    1. import std.io
    2. let mut r = { items: [1, 2] }
    3. let saved = r
    4. r.items[0] = 5
    5. io.writeLine("{saved.items[0]}:{r.items[0]}")
    Ожидаемый выводКод завершения 0
    1:5
    
    $ topaz run example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 1:5

    Insert and remove entries in an independent Map value

    Ссылка
    example.tpzInsert and remove entries in an independent Map value
    1. import std.io
    2. let entries = map { "one": 1 }
    3. let mut changed = entries
    4. changed.insert("two", 2)
    5. io.writeLine("{entries.length}:{changed.length}")
    6. changed.remove("one")
    7. io.writeLine("{entries.keys[0]}:{changed.keys[0]}")
    Ожидаемый выводКод завершения 0
    1:2
    one:two
    
    $ topaz run example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 1:2
    2. one:two

    Add and remove members in an independent Set value

    Ссылка
    example.tpzAdd and remove members in an independent Set value
    1. import std.io
    2. let values = set { 1 }
    3. let mut changed = values
    4. changed.add(2)
    5. io.writeLine("{values.length}:{changed.length}")
    6. changed.remove(1)
    7. io.writeLine("{1 in values}:{1 in changed}")
    Ожидаемый выводКод завершения 0
    1:2
    true:false
    
    $ topaz run example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 1:2
    2. true:false

    A mutable capture changes one variable and preserves earlier values

    Ссылка
    example.tpzA mutable capture changes one variable and preserves earlier values
    1. import std.io
    2. let mut items = [1]
    3. let before = items
    4. let append: () -> () = () => { items.push(2) }
    5. append()
    6. io.writeLine("{items.length}:{before.length}")
    Ожидаемый выводКод завершения 0
    2:1
    
    $ topaz run example.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 2:1

    Pending

    Ссылка

    Related references

    Ссылка

    Types →

    Functions and generics →

    TPZ5001 →

    Reserved binding name →

    Invalid assignment target →

    Immutable binding mutation →

    Unbound name →

    Module namespace collision →

    Redeclaration →

    Unexpected token →

    Initializer reads a later binding →

    Меню

    Загрузка →