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

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

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

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

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

    Язык · 12 глав · 12 правил

    Ошибки и распространение

    Read and check Result propagation and callable-local Result or Option propagation with postfix ?.

    Scope and ownership

    Ссылка

    Use this chapter to inspect error propagation and locate incompatible operand or return types.

    This page owns postfix Result propagation and callable-local Result or Option propagation. Types owns general type compatibility. Pattern matching owns case syntax. Blocks and control flow owns explicit returns and cleanup ordering. Functions and generics owns return annotations and inference. Diagnostic entries own code-specific explanations. Command entries own process results.

    Propagation syntax

    Ссылка
    EBNF
    1. Propagation = PostfixExpression "?" ;

    Expression precedence is specified by Expressions and operators.

    Правилоtopaz.rule.failure-and-propagation.postfix

    Postfix operand

    Postfix ? takes the preceding postfix expression as its operand.

    Причина

    Postfix placement keeps the operation that may fail next to the point that forwards its error. It follows the binding order of calls and member access.

    Values and early return

    Ссылка
    Правилоtopaz.rule.failure-and-propagation.evaluate-once

    Operand evaluation

    In a named function, ? evaluates its Result operand once.

    The corresponding lambda and callback behavior follows lambda and callback propagation.

    Причина

    Repeated evaluation could repeat input, output, or mutation before deciding whether to return an error.

    Правилоtopaz.rule.failure-and-propagation.ok

    Successful operand

    When the operand produces Ok(value), ? yields value and evaluation continues in the enclosing named function.

    The corresponding lambda and callback behavior follows lambda and callback propagation.

    Причина

    A successful operation supplies the value needed by later expressions without ending the function.

    Правилоtopaz.rule.failure-and-propagation.err

    Error return

    When the operand produces Err(error), ? returns that Result with its error payload from the enclosing named function. Subsequent expressions in its body are skipped.

    The corresponding lambda and callback behavior follows lambda and callback propagation.

    Причина

    Preserving the error payload keeps failure information intact. Skipping the remaining body prevents later work from using a value that was not produced.

    Правилоtopaz.rule.failure-and-propagation.callback-propagation

    Propagation returns from the current callable

    Postfix ? in a lambda or callback targets that callable's own return. Each function boundary has one propagation destination. For a Result-returning lambda, an Ok yields its payload and an Err returns the original error Result from that invocation. In an Option-returning lambda, Some yields its payload and None returns None from that invocation. The remaining lambda body is skipped on either return. The surrounding function continues after the call and can propagate the returned value with its own ?.

    A lambda using ? must return Result or Option. Propagating a Result from a lambda returning another type uses the same TPZ5001 rejection as the named function return rule. The expected callback type still applies. A Result-returning lambda does not satisfy a bool callback slot such as filter. An undetermined Result error type requires an annotation with TPZ5022 under the error annotation rule.

    Причина

    Each function boundary gives ? one return destination. A standard function such as map or filter can call a callback without handling nonlocal control transfer.

    Правилоtopaz.rule.failure-and-propagation.operand-fault

    Operand fault

    A runtime fault raised while evaluating the operand continues as a runtime fault.

    An ordinary runtime fault follows fault termination.

    A runtime fault remains a fault inside a lambda or callback. It is not a returned Err or None under lambda and callback propagation.

    Причина

    A runtime fault interrupts evaluation, while an Err is an ordinary value. Keeping these paths distinct prevents propagation from silently converting a fault into a Result.

    Operand and return types

    Ссылка
    Правилоtopaz.rule.failure-and-propagation.result-type

    Success type

    For an operand of type Result<T, E>, operand? has type T.

    Причина

    Successful propagation supplies the payload to the next expression. Its type is the success type because the Result wrapper has been handled.

    Правилоtopaz.rule.failure-and-propagation.operand-required

    Result operand requirement

    In a named function returning Result, a propagation operand with a resolved non-Result type is rejected during checking with TPZ5001. Option-returning lambdas follow the callable propagation rule.

    Option-returning lambdas follow lambda and callback propagation.

    Причина

    A Result return needs an error Result to forward. An Option operand supplies no error payload for that Result return.

    Правилоtopaz.rule.failure-and-propagation.function-context

    Enclosing function

    Using ? without an enclosing function return context is rejected during checking with TPZ5001.

    The corresponding lambda and callback behavior follows lambda and callback propagation.

    Причина

    Propagation needs a function return target. Without one, the error has no destination.

    Правилоtopaz.rule.failure-and-propagation.result-return

    Result return requirement

    Propagating a Result from a function with a resolved non-Result return type is rejected during checking with TPZ5001.

    An undetermined Result error type follows the annotation requirement.

    The corresponding lambda and callback behavior follows lambda and callback propagation.

    Причина

    The enclosing return type must admit the error Result that propagation returns. Otherwise the function could produce a value outside its declared type.

    Правилоtopaz.rule.failure-and-propagation.error-assignability

    Error type compatibility

    For an operand of type Result<T, E> in a function returning Result<U, F>, E must be assignable to F. Incompatible resolved error types produce TPZ5001 during checking. The propagation step does not compare T with U.

    Причина

    An error can leave the function at this point, so it must fit the declared error type. The success payload remains local and can be transformed before return.

    Правилоtopaz.rule.failure-and-propagation.error-annotation

    Annotating an unresolved Result error type

    If the Result error type cannot be determined, checking rejects the expression with TPZ5022 and requires a type annotation. Inference does not substitute a broad fallback type. This is the same diagnostic as the return annotation requirement.

    This uses the same diagnostic as return annotation requirements. Lambda and callback propagation gives each lambda and callback its own return destination.

    The corresponding lambda and callback behavior follows lambda and callback propagation.

    Причина

    Return inference and Result error inference use the same annotation rule and diagnostic. The program therefore has a determined error type before emission.

    Examples and counterexamples

    Ссылка

    The checking examples pair rejected files with complete repairs. The execution example makes operand evaluation and continuation visible.

    Option operand

    Ссылка
    example.tpzOption operandОткрыть песочницу →
    1. function advance(value: Option<int>) -> Result<int, string> {
    2. let number: int = value?
    3. Ok(number + 1)
    4. }
    Зафиксированный выводКод завершения 1
    Нет стандартного вывода.
    error[TPZ5001]: `?` requires a Result value, found `Option<int>`
     --> example.tpz:2:23
      |
    2 |     let number: int = value?
      |                       ^^^^^^
    
    example.tpz: 1 type diagnostic
    
    $ topaz check example.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

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

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

    • TPZ5001 →

      result-required-for-propagation at example.tpz:2:23

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

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

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

    Наблюдаемый вывод ошибок
    1. error[TPZ5001]: `?` requires a Result value, found `Option<int>`
    2. --> example.tpz:2:23
    3. |
    4. 2 | let number: int = value?
    5. | ^^^^^^
    6. example.tpz: 1 type diagnostic
    • Пройдено · expected nonzero; observed 1
    • Пройдено · checking TPZ5001; cause result-required-for-propagation; primary location asserted; additional diagnostics allow
    • Пройдено · stdout matches the authored expectation

    Result operand

    Ссылка
    example.tpzResult operandОткрыть песочницу →
    1. function advance(value: Result<int, string>) -> Result<int, string> {
    2. let number: int = value?
    3. Ok(number + 1)
    4. }
    5. let success: Result<int, string> = advance(Ok(4))
    6. let failure: Result<int, string> = advance(Err("missing"))
    Зафиксированный выводКод завершения 0
    Нет стандартного вывода.
    $ topaz check example.tpz --compiler self --format json · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

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

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

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

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

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

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

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

    Integer return type

    Ссылка
    example.tpzInteger return typeОткрыть песочницу →
    1. function read(value: Result<int, string>) -> int {
    2. value?
    3. }
    Зафиксированный выводКод завершения 1
    Нет стандартного вывода.
    error[TPZ5001]: `?` propagates an error, but the function returns `int`, not a Result
     --> example.tpz:2:5
      |
    2 |     value?
      |     ^^^^^^
    
    example.tpz: 1 type diagnostic
    
    $ topaz check example.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

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

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

    • TPZ5001 →

      propagation-requires-result-return at example.tpz:2:5

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

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

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

    Наблюдаемый вывод ошибок
    1. error[TPZ5001]: `?` propagates an error, but the function returns `int`, not a Result
    2. --> example.tpz:2:5
    3. |
    4. 2 | value?
    5. | ^^^^^^
    6. example.tpz: 1 type diagnostic
    • Пройдено · expected nonzero; observed 1
    • Пройдено · checking TPZ5001; cause propagation-requires-result-return; primary location asserted; additional diagnostics allow
    • Пройдено · stdout matches the authored expectation

    Result return type

    Ссылка
    example.tpzResult return typeОткрыть песочницу →
    1. function read(value: Result<int, string>) -> Result<int, string> {
    2. let number: int = value?
    3. Ok(number)
    4. }
    Зафиксированный выводКод завершения 0
    Нет стандартного вывода.
    $ topaz check example.tpz --compiler self --format json · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

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

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

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

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

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

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

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

    Incompatible error types

    Ссылка
    example.tpzIncompatible error typesОткрыть песочницу →
    1. function relay(value: Result<int, string>) -> Result<int, int> {
    2. let number: int = value?
    3. Ok(number)
    4. }
    Зафиксированный выводКод завершения 1
    Нет стандартного вывода.
    error[TPZ5001]: expected `int`, found `string`
     --> example.tpz:2:23
      |
    2 |     let number: int = value?
      |                       ^^^^^^
    
    example.tpz: 1 type diagnostic
    
    $ topaz check example.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

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

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

    • TPZ5001 →

      propagated-error-type-not-assignable at example.tpz:2:23

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

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

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

    Наблюдаемый вывод ошибок
    1. error[TPZ5001]: expected `int`, found `string`
    2. --> example.tpz:2:23
    3. |
    4. 2 | let number: int = value?
    5. | ^^^^^^
    6. example.tpz: 1 type diagnostic
    • Пройдено · expected nonzero; observed 1
    • Пройдено · checking TPZ5001; cause propagated-error-type-not-assignable; primary location asserted; additional diagnostics allow
    • Пройдено · stdout matches the authored expectation

    Matching error types

    Ссылка
    example.tpzMatching error typesОткрыть песочницу →
    1. function relay(value: Result<int, string>) -> Result<int, string> {
    2. let number: int = value?
    3. Ok(number)
    4. }
    Зафиксированный выводКод завершения 0
    Нет стандартного вывода.
    $ topaz check example.tpz --compiler self --format json · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

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

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

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

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

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

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

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

    Propagation at top level

    Ссылка
    example.tpzPropagation at top levelОткрыть песочницу →
    1. let value: Result<int, string> = Ok(1)
    2. let number: int = value?
    Зафиксированный выводКод завершения 1
    Нет стандартного вывода.
    error[TPZ5001]: `return` outside a function
     --> example.tpz:2:19
      |
    2 | let number: int = value?
      |                   ^^^^^^
    
    example.tpz: 1 type diagnostic
    
    $ topaz check example.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

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

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

    • TPZ5001 →

      propagation-outside-function at example.tpz:2:19

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

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

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

    Наблюдаемый вывод ошибок
    1. error[TPZ5001]: `return` outside a function
    2. --> example.tpz:2:19
    3. |
    4. 2 | let number: int = value?
    5. | ^^^^^^
    6. example.tpz: 1 type diagnostic
    • Пройдено · expected nonzero; observed 1
    • Пройдено · checking TPZ5001; cause propagation-outside-function; primary location asserted; additional diagnostics allow
    • Пройдено · stdout matches the authored expectation

    Observe success and early error return

    Ссылка
    example.tpzObserve success and early error returnОткрыть песочницу →
    1. import std.io
    2. function observe(value: Result<int, string>) -> Result<int, string> {
    3. io.writeLine("operand")
    4. value
    5. }
    6. function advance(value: Result<int, string>) -> Result<int, string> {
    7. let number: int = observe(value)?
    8. io.writeLine("continued")
    9. Ok(number + 1)
    10. }
    11. let success: Result<int, string> = advance(Ok(4))
    12. match (success) {
    13. case Ok(number) => io.writeLine("ok {number}")
    14. case Err(error) => io.writeLine("unexpected {error}")
    15. }
    16. let failure: Result<int, string> = advance(Err("missing"))
    17. match (failure) {
    18. case Ok(number) => io.writeLine("unexpected {number}")
    19. case Err(error) => io.writeLine("error {error}")
    20. }
    Зафиксированный выводКод завершения 0
    operand
    continued
    ok 5
    operand
    error missing
    
    $ topaz run example.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

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

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

    Ожидаемый стандартный вывод
    1. operand
    2. continued
    3. ok 5
    4. operand
    5. error missing
    Наблюдаемые утверждения · Пройдено · 5.21.3

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

    Наблюдаемый стандартный вывод
    1. operand
    2. continued
    3. ok 5
    4. operand
    5. error missing

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

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

    An unknown Result error type requires an annotation

    Ссылка
    main.tpzAn unknown Result error type requires an annotationОткрыть песочницу →
    1. function value() { Ok(1) }
    2. let result = value()
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check main.tpz --compiler self · Целевой продукт 5.21.3
    Ожидаемый результат

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

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

    • TPZ5022 →

      result-error-annotation-required at main.tpz:1:10

    A Result return annotation fixes the error type

    Ссылка
    main.tpzA Result return annotation fixes the error typeОткрыть песочницу →
    1. import std.io
    2. function value() -> Result<int, string> { Ok(1) }
    3. let result = match (value()) {
    4. case Ok(number) => number
    5. case Err(_) => 0
    6. }
    7. io.writeLine("{result}")
    Ожидаемый выводКод завершения 0
    1
    
    $ topaz run main.tpz --compiler self · Целевой продукт 5.21.3
    Ожидаемый результат

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

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

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

    Mapping a propagating lambda produces an array of Results

    Ссылка
    main.tpzMapping a propagating lambda produces an array of ResultsОткрыть песочницу →
    1. import std.io
    2. function surrounding() -> int {
    3. let inputs: Array<Result<int, string>> = [Ok(1), Err("stop"), Ok(3)]
    4. let advance: (Result<int, string>) -> Result<int, string> = (value) => {
    5. let number = value?
    6. io.writeLine("lambda {number}")
    7. Ok(number + 1)
    8. }
    9. let results: Array<Result<int, string>> = inputs.map(advance)
    10. io.writeLine("after map")
    11. for result in (results) {
    12. match (result) {
    13. case Ok(number) => io.writeLine("ok {number}")
    14. case Err(error) => io.writeLine("err {error}")
    15. }
    16. }
    17. 7
    18. }
    19. io.writeLine("{surrounding()}")
    Зафиксированный выводКод завершения 0
    lambda 1
    lambda 3
    after map
    ok 2
    err stop
    ok 4
    7
    
    $ topaz run main.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

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

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

    Ожидаемый стандартный вывод
    1. lambda 1
    2. lambda 3
    3. after map
    4. ok 2
    5. err stop
    6. ok 4
    7. 7
    Наблюдаемые утверждения · Пройдено · 5.21.3

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

    Наблюдаемый стандартный вывод
    1. lambda 1
    2. lambda 3
    3. after map
    4. ok 2
    5. err stop
    6. ok 4
    7. 7

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

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

    None returns from its lambda while the caller continues

    Ссылка
    main.tpzNone returns from its lambda while the caller continuesОткрыть песочницу →
    1. import std.io
    2. let advance: (Option<int>) -> Option<int> = (value) => {
    3. let number = value?
    4. io.writeLine("some {number}")
    5. Some(number + 1)
    6. }
    7. let missing = advance(None())
    8. io.writeLine("after none")
    9. match (missing) {
    10. case Some(number) => io.writeLine("{number}")
    11. case None() => io.writeLine("none")
    12. }
    13. let present = advance(Some(2))
    14. match (present) {
    15. case Some(number) => io.writeLine("{number}")
    16. case None() => io.writeLine("none")
    17. }
    Зафиксированный выводКод завершения 1
    Нет стандартного вывода.
    error[TPZ5001]: `?` requires a Result value, found `Option<int>`
     --> main.tpz:3:18
      |
    3 |     let number = value?
      |                  ^^^^^^
    
    main.tpz: 1 type diagnostic
    
    $ topaz run main.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

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

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

    Ожидаемый стандартный вывод
    1. after none
    2. none
    3. some 2
    4. 3
    Наблюдаемые утверждения · Не пройдено · 5.21.3

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

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

    Наблюдаемый вывод ошибок
    1. error[TPZ5001]: `?` requires a Result value, found `Option<int>`
    2. --> main.tpz:3:18
    3. |
    4. 3 | let number = value?
    5. | ^^^^^^
    6. main.tpz: 1 type diagnostic
    • Не пройдено · expected 0; observed 1
    • Не пройдено · stdout matches the authored expectation
    • Не пройдено · stderr matches the authored expectation

    An integer-returning lambda cannot propagate a Result

    Ссылка
    main.tpzAn integer-returning lambda cannot propagate a ResultОткрыть песочницу →
    1. let read: (Result<int, string>) -> int = (value) => {
    2. value?
    3. }
    Зафиксированный выводКод завершения 1
    Нет стандартного вывода.
    error[TPZ5001]: `?` propagates an error, but the function returns `int`, not a Result
     --> main.tpz:2:5
      |
    2 |     value?
      |     ^^^^^^
    
    main.tpz: 1 type diagnostic
    
    $ topaz check main.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

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

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

    • TPZ5001 →

      propagation-requires-result-return at main.tpz:2:5

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

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

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

    Наблюдаемый вывод ошибок
    1. error[TPZ5001]: `?` propagates an error, but the function returns `int`, not a Result
    2. --> main.tpz:2:5
    3. |
    4. 2 | value?
    5. | ^^^^^^
    6. main.tpz: 1 type diagnostic
    • Пройдено · expected nonzero; observed 1
    • Пройдено · stdout matches the authored expectation
    • Пройдено · checking TPZ5001; cause propagation-requires-result-return; primary location asserted; additional diagnostics allow

    A propagating lambda needs a determined Result error type

    Ссылка
    main.tpzA propagating lambda needs a determined Result error typeОткрыть песочницу →
    1. let lift = () => {
    2. let value = Ok(1)?
    3. Ok(value)
    4. }
    Зафиксированный выводКод завершения 0
    main.tpz: types-ok (1 module)
    main.tpz: resolve-ok (1 module)
    
    $ topaz check main.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

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

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

    • TPZ5022 →

      result-error-annotation-required at main.tpz:1:12

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

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

    Наблюдаемый стандартный вывод
    1. main.tpz: types-ok (1 module)
    2. main.tpz: resolve-ok (1 module)

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

    • Не пройдено · expected nonzero; observed 0
    • Не пройдено · stdout matches the authored expectation
    • Не пройдено · checking TPZ5022; cause result-error-annotation-required; primary location asserted; additional diagnostics allow

    Filter rejects a Result-returning callback where bool is required

    Ссылка
    main.tpzFilter rejects a Result-returning callback where bool is requiredОткрыть песочницу →
    1. let predicate: (Result<int, string>) -> Result<bool, string> = (value) => {
    2. let number = value?
    3. Ok(number > 0)
    4. }
    5. let inputs: Array<Result<int, string>> = [Ok(1)]
    6. let selected = inputs.filter(predicate)
    Зафиксированный выводКод завершения 1
    Нет стандартного вывода.
    error[TPZ5001]: expected `(Result<int, string>) -> bool`, found `(Result<int, string>) -> Result<bool, string>`
     --> main.tpz:6:30
      |
    6 | let selected = inputs.filter(predicate)
      |                              ^^^^^^^^^
    
    main.tpz: 1 type diagnostic
    
    $ topaz check main.tpz --compiler self · Зафиксировано с Топазом 5.21.3
    Ожидаемый результат

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

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

    • TPZ5001 →

      callback-return-type-mismatch at main.tpz:6:30

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

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

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

    Наблюдаемый вывод ошибок
    1. error[TPZ5001]: expected `(Result<int, string>) -> bool`, found `(Result<int, string>) -> Result<bool, string>`
    2. --> main.tpz:6:30
    3. |
    4. 6 | let selected = inputs.filter(predicate)
    5. | ^^^^^^^^^
    6. main.tpz: 1 type diagnostic
    • Пройдено · expected nonzero; observed 1
    • Пройдено · stdout matches the authored expectation
    • Пройдено · checking TPZ5001; cause callback-return-type-mismatch; primary location asserted; additional diagnostics allow

    Pending contracts

    Ссылка

    Related references

    Ссылка

    TPZ5001 →

    Functions and generics →

    check →

    TPZ5022 →

    Меню

    Загрузка →