본문으로 건너뛰기
토파즈6.0 · 출시 전
다운로드 →

문서 검색

명세 6.0

방향키로 결과를 고르고 Enter를 눌러 여세요.

API 이름, 진단 번호, 규칙 또는 프로젝트 주제를 입력하세요.

    언어 · 13장 · 25개 규칙

    모듈과 가시성

    Use this page to split a source program into files and choose which declarations other files can access.

    Scope and ownership

    링크

    This page covers source modules, dotted module paths, import bindings, exports, and visibility. Function declarations and bounds belong to Functions and generics. The check command owns entry-file and source-root selection. Dependency acquisition, locks, targets, and individual standard-library APIs have separate owners.

    Import and export syntax

    링크
    EBNF
    1. ModulePath = Identifier ("." Identifier)* ;
    2. ImportItem = NamespaceImport | SelectedImport ;
    3. NamespaceImport = "import" ModulePath ("as" Identifier)? ;
    4. SelectedImport =
    5. "import" ModulePath "{" ImportSpec ("," ImportSpec)* ","? "}" ;
    6. ImportSpec = Identifier ("as" Identifier)? ;
    7. ExportShape = "export" ExportableDeclaration ;

    This source-syntax excerpt is transcribed from the parser. Identifier spelling, statement separators, declaration bodies, and binding patterns use their own productions.

    The complete grammar applies identifier-equality guards to aliases: a namespace alias differs from the final module-path segment, and a selected alias differs from the selected source name. This excerpt shows the production shape; the alias rule specifies that additional constraint.

    Files and the source program

    링크

    The uniform initialization rules are the recommendation recorded in PR #41 for the remaining 6.0 design work. Current SELF differences are listed as limitations with unchanged expected assertions. The example scope remains Topaz 5.21 / public product 5.21.3 until the separate documentation version split.

    규칙topaz.rule.modules.source-path

    Source paths and module identity

    An ordinary source module uses a dotted identifier path. Under the selected source root, each dot becomes a path separator and the file name ends in .tpz. For example, geometry.point selects geometry/point.tpz. Its logical identity is the dotted relative path without the extension.

    이유

    A dotted name gives each source module one logical identity independent of the host path separator. The same name determines the source file.

    규칙topaz.rule.modules.source-program

    The source program

    The entry file and the source files reached transitively through its imports form the source program.

    이유

    Following imports includes the files needed by the entry program without making unrelated neighboring files part of it.

    규칙topaz.rule.modules.import-prologue

    Import placement

    Imports must precede every other top-level item in a file. A later import is rejected with TPZ2010.

    이유

    A single prologue makes dependencies visible before executable items. Import placement then does not suggest an order among those items.

    규칙topaz.rule.modules.imported-top-level

    The same statements in every source file

    Entry files and imported files use the same top-level statement grammar. Both admit declarations, free expressions, assignments, and loops. Binding initializers and free expressions use the ordinary effect rules. Import placement, visibility, mutability, control-flow targets, and all other context checks apply equally to both file roles. Importing a file does not add a statement-form restriction.

    이유

    The meaning of a source file should not depend on whether it is selected as the entry or reached through an import. Effectful binding initializers already run during module initialization; deterministic ordering and readiness rules address those effects directly. Uniform statement forms let ordinary general-purpose code move between files without a wrapper function or dummy binding.

    규칙topaz.rule.modules.initialization-order

    Dependency order and one initialization

    Resolve the complete source program before initialization. Initialize source modules serially, completing every dependency before its importer. At each step, choose the lexicographically smallest canonical logical module identity among modules whose dependencies have completed; compare identities by Unicode scalar value. Import spelling order and local aliases do not affect this order. After constant processing, execute ordinary top-level items in source order. Every module initializes exactly once per program invocation, including when multiple import paths reach it in a diamond. All importers share the same completed module state. A new program invocation, including a new host invocation of an exported function, creates fresh module state and repeats initialization.

    이유

    A file has one logical identity and one initialized state within an invocation. A dependency must finish before its importer can use it. Choosing the smallest ready identity makes the result stable when import lines or local aliases change, and sharing diamond dependencies prevents duplicate initialization effects.

    규칙topaz.rule.modules.initialization-cycle

    Reject cycles before initialization

    A source import cycle, including a module importing itself, is rejected with TPZ3006 during resolution. The diagnostic identifies an import edge in the cycle. No module initialization or entry execution begins for a rejected graph. Break the cycle by moving shared declarations into a dependency or removing the back edge.

    이유

    A cycle has no dependency-first initialization order. Rejecting it before effects begin keeps every import bound to a fully initialized module and avoids a second set of rules for partially initialized exports.

    규칙topaz.rule.modules.initialization-failure

    An initialization fault stops the invocation

    If module initialization faults, abort the program invocation immediately. Do not execute remaining items in that module, initialize later modules, or start a waiting importer. Already completed effects remain visible; initialization provides no rollback. Report the original fault code and primary source location. An added initialization-context message does not change that diagnostic identity.

    이유

    Initialization uses ordinary execution and effects. Stopping at the first fault preserves the dependency guarantee, while retaining the original diagnostic locates the failing operation. General host effects cannot be promised transactional rollback.

    Namespace and selected imports

    링크
    규칙topaz.rule.modules.namespace-binding

    Namespace import bindings

    A namespace import binds the final path segment as its local namespace name. An explicit as alias supplies that name instead. Select a declaration with namespace.member.

    이유

    A namespace groups a module's exported names under one local binding. An alias resolves collisions between modules with the same final path segment.

    규칙topaz.rule.modules.selected-bindings

    Selected import bindings

    A selected import binds each chosen export directly under its source name or its selection alias. Renaming the local binding preserves which source declaration it denotes. A selection list creates no namespace binding.

    이유

    Selecting exports makes each imported dependency explicit in the local scope. An alias can resolve a local name collision while retaining the source declaration.

    규칙topaz.rule.modules.import-alias-name

    An alias changes the local name

    Omit as when an import keeps its default binding name. A namespace alias must differ from the final module-path segment; a selected alias must differ from that selected source name. An explicit alias repeating the default identifier is rejected with TPZ2009 during parsing, at the alias identifier. An alias that changes the local name remains permitted under the ordinary import visibility and collision rules.

    The intended new diagnostic message is “redundant import alias {name}; omit as {name}”. Here {name} is the alias identifier. This is the proposed contract, not an observed current SELF message. Current SELF accepts the redundant form, as recorded in the limitation. TPZ2009 already canonically identifies unsupported module export/import composition; this rule adds a distinct cause within that identity.

    이유

    The default namespace or selected source name already defines the local binding. Repeating that name after as creates a second spelling for exactly the same import without adding information. Omitting a redundant alias keeps one spelling for the default binding, while an actual rename remains available to choose a different local name.

    규칙topaz.rule.modules.selection-list

    Selection-list requirements

    A selection list must contain at least one name. Selected source names and resulting local names must each be unique. Violating these requirements is rejected with TPZ2011.

    이유

    An empty selection introduces no names. Repeated source or local names would duplicate an import or leave a local binding ambiguous.

    규칙topaz.rule.modules.import-form-choice

    Choose a namespace or selection

    A namespace alias and a selection list cannot appear in the same import item. Their combination is rejected with TPZ2009.

    이유

    A namespace binding and a selection introduce different local names. Separating them keeps one import item from creating both sets implicitly.

    규칙topaz.rule.modules.repeated-module

    One import item per module

    A logical module may appear in at most one import item in an importing file. Repeating it is rejected with TPZ3017.

    이유

    One import item keeps a module's dependency and local naming choices together. Repeated items would split the same dependency across declarations.

    Exports and read-only import bindings

    링크
    규칙topaz.rule.modules.declaration-visibility

    Public and private declarations

    Prefix an otherwise valid function, let, const, type alias, enum, record, newtype, or protocol declaration with export to publish its binding. Without that prefix, the declaration remains module-private.

    이유

    Private declarations can change without changing a module's public names. Placing export on the declaration gives each published binding one visible definition.

    규칙topaz.rule.modules.exported-let-shape

    The shape of an exported binding

    An exported immutable let uses an ordinary let pattern and optional type annotation. The pattern must bind at least one name; otherwise TPZ2007 rejects it during parsing. Every bound name becomes an immutable export with its module-and-name identity. Evaluate the initializer once, match the complete pattern, then install all bindings. Ordinary pattern typing, duplicate-name, and refutability checks still apply. If evaluation or matching faults, install no binding from that pattern and stop module initialization; earlier external effects remain. Check every resolved bound type for private nominal exposure. Public types are the extracted binding types, not the temporary initializer container. Module exports are published after successful initialization.

    이유

    Export changes visibility, so an immutable binding uses the same pattern and type rules in a private or public declaration. Requiring temporary private bindings would repeat the same decomposition. Each bound name is a public module binding; a pattern without a name publishes nothing and uses plain let. The initializer and pattern match therefore stay one operation, independent of how many names become public.

    규칙topaz.rule.modules.exported-let-mutability

    Exported bindings are immutable

    An exported let binding must be immutable. The form export let mut is rejected with TPZ3011 during resolution.

    이유

    An immutable exported binding prevents another module from depending on reassignment of shared module state. Updates can pass through an exported function with an explicit interface.

    규칙topaz.rule.modules.selected-visibility

    Namespace imports and selected exports

    A namespace import may target a module with an empty export table. That module initializes normally and the bound namespace has no public members. Selecting a private or absent name is rejected with TPZ3009 during resolution, including when the target exports no names. Initialization does not require a dummy export or a separate import form.

    이유

    Imports expose only public declarations, so selecting a name must consult the export table. Initialization is independent of that table: a module used for its effects needs the same namespace import as any other module, without a dummy export or a separate side-effect import syntax.

    규칙topaz.rule.modules.namespace-visibility

    Visibility through a namespace

    A value or type selected through a namespace must name an exported declaration. The requirement applies in every context, including record field defaults. A private or absent member is rejected with TPZ3009 during resolution.

    이유

    Namespace access must respect the same public names as selected imports. Qualification must not grant access to private module declarations.

    규칙topaz.rule.modules.import-assignment

    Rebinding imported declarations

    Direct replacement of a selected imported binding, including an alias, or an imported namespace member is rejected during resolution with TPZ3015. This rejection precedes the immutable-root check. Data mutation and mutable local values follow the imported value rule.

    See imported values for data mutation and mutable local values.

    이유

    An imported binding belongs to its defining module. Rejecting replacement prevents an importing module from changing what other readers observe through that name.

    규칙topaz.rule.modules.public-type-surface

    Resolved public type visibility

    An exported declaration publishes its resolved type, whether that type is annotated or inferred. Expand transparent type aliases before checking visibility. Every reachable record, enum, or newtype identity must be exported by its defining module. Check nested type components and type arguments recursively, including collections, structural records, unions, and function types. The rule covers function parameters and results, let and const bindings, type aliases, enum payloads, record fields, newtype bases, and exported protocol method parameters and results. A private alias whose expansion contains accessible types is accepted. A reachable private nominal type is rejected with TPZ3014 in the resolve phase. The primary location is the offending exported type reference when annotated, or the exported declaration's name when inferred.

    이유

    Exporters publish the same type whether an annotation or inference determines it. Checking resolved identities prevents annotation spelling from changing visibility. Transparent aliases introduce no new identity, so callers need the expanded type rather than the private alias name.

    An exported function may expose an exported user protocol bound

    링크
    example.tpzAn exported function may expose an exported user protocol bound플레이그라운드 열기 →
    1. export protocol Labelled { function label(value: Self) -> string }
    2. export function describe<T: Labelled>(value: T) -> string { Labelled.label(value) }
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check example.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    A private protocol is not selected through import

    링크
    example.tpzA private protocol is not selected through import플레이그라운드 열기 →
    1. import contracts { Hidden }
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check example.tpz --format json · 대상 제품 5.21.3
    contracts.tpzA private protocol is not selected through import플레이그라운드 열기 →
    1. protocol Hidden { function label(value: Self) -> string }
    2. export let marker = 0
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3009 →

      protocol-name-not-exported at example.tpz:1:20

    An exported protocol cannot expose a private nominal parameter type

    링크
    example.tpzAn exported protocol cannot expose a private nominal parameter type플레이그라운드 열기 →
    1. record Hidden { n: int }
    2. export protocol Render { function render(value: Self, input: Hidden) -> string }
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check example.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3014 →

      modules-public-private-nominal at example.tpz:2:62

    An exported protocol signature may use an exported nominal type

    링크
    example.tpzAn exported protocol signature may use an exported nominal type플레이그라운드 열기 →
    1. export record Input { n: int }
    2. export protocol Render { function render(value: Self, input: Input) -> string }
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check example.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    규칙topaz.rule.modules.imported-values

    Imported values

    An imported value is an immutable binding. The importing module cannot change its data through that binding. let mut local = imported receives an independent data value under collection value semantics. Changing the local leaves the exported value unchanged. Imported host resource handles, such as File, retain shared resource state.

    Imported data follows collection value semantics. Import assignment rejects replacement. Immutable assignment rejects writes through an immutable root.

    이유

    Importing a data value follows the same value semantics as assigning it. A mutable local therefore cannot change the exporting module's value.

    Rejected source forms

    링크
    규칙topaz.rule.modules.reserved-import-forms

    Reserved import spellings

    A use item and a string or template module path are rejected with TPZ2008.

    이유

    Dotted imports give source dependencies one spelling. A second keyword or string path would name the same module through another syntax.

    규칙topaz.rule.modules.rejected-export-forms

    Rejected export spellings

    The forms export { name } and export import module are rejected with TPZ2009.

    이유

    An export prefix keeps visibility at the declaration. Separate export lists or import exports would give publication another place and spelling.

    Complete import and export examples

    링크

    Save the complete file set shown for an example, then use its displayed command.

    Select exports and rename a local binding

    링크
    main.tpzSelect exports and rename a local binding플레이그라운드 열기 →
    1. import helpers { double as twice, increment }
    2. let result: int = twice(20) + increment
    기록된 출력종료 코드 0
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 기록에 사용한 토파즈 5.21.3
    helpers.tpzSelect exports and rename a local binding플레이그라운드 열기 →
    1. export function double(value: int) -> int {
    2. value + value
    3. }
    4. export let increment: int = 1
    5. let secret: int = 99
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 0.

    표준 출력 없음.

    표준 오류 출력 없음.

    • 통과 · expected 0; observed 0
    • 통과 · stdout matches the authored expectation
    • 통과 · stderr matches the authored expectation

    Save helpers.tpz beside main.tpz. The following run example uses the same selected import and prints its result.

    Run a selected import with an alias

    링크
    main.tpzRun a selected import with an alias플레이그라운드 열기 →
    1. import std.io { writeLine }
    2. import helpers { double as twice, increment }
    3. let result: int = twice(20) + increment
    4. writeLine("{result}")
    기록된 출력종료 코드 0
    41
    
    $ topaz run main.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    helpers.tpzRun a selected import with an alias플레이그라운드 열기 →
    1. export function double(value: int) -> int {
    2. value + value
    3. }
    4. export let increment: int = 1
    5. let secret: int = 99
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 41
    관측한 단언 · 통과 · 5.21.3

    종료 코드 0.

    관측한 표준 출력
    1. 41

    표준 오류 출력 없음.

    • 통과 · expected 0; observed 0
    • 통과 · stdout matches the authored expectation
    • 통과 · stderr matches the authored expectation

    Bind a namespace under its final path segment

    링크
    main.tpzBind a namespace under its final path segment플레이그라운드 열기 →
    1. import helpers
    2. let result: int = helpers.double(21)
    기록된 출력종료 코드 0
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 기록에 사용한 토파즈 5.21.3
    helpers.tpzBind a namespace under its final path segment플레이그라운드 열기 →
    1. export function double(value: int) -> int {
    2. value + value
    3. }
    4. export let increment: int = 1
    5. let secret: int = 99
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 0.

    표준 출력 없음.

    표준 오류 출력 없음.

    • 통과 · expected 0; observed 0
    • 통과 · stdout matches the authored expectation
    • 통과 · stderr matches the authored expectation

    Choose a namespace name

    링크
    main.tpzChoose a namespace name플레이그라운드 열기 →
    1. import helpers as numbers
    2. let result: int = numbers.double(21)
    기록된 출력종료 코드 0
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 기록에 사용한 토파즈 5.21.3
    helpers.tpzChoose a namespace name플레이그라운드 열기 →
    1. export function double(value: int) -> int {
    2. value + value
    3. }
    4. export let increment: int = 1
    5. let secret: int = 99
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 0.

    표준 출력 없음.

    표준 오류 출력 없음.

    • 통과 · expected 0; observed 0
    • 통과 · stdout matches the authored expectation
    • 통과 · stderr matches the authored expectation

    Export an immutable binding

    링크
    main.tpzExport an immutable binding플레이그라운드 열기 →
    1. import counters { count }
    2. let value: int = count
    기록된 출력종료 코드 0
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 기록에 사용한 토파즈 5.21.3
    counters.tpzExport an immutable binding플레이그라운드 열기 →
    1. export let count: int = 0
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 0.

    표준 출력 없음.

    표준 오류 출력 없음.

    • 통과 · expected 0; observed 0
    • 통과 · stdout matches the authored expectation
    • 통과 · stderr matches the authored expectation

    Use an exported value in a record default

    링크
    main.tpzUse an exported value in a record default플레이그라운드 열기 →
    1. import std.io
    2. import defaults
    3. record Item {
    4. value: int = defaults.seed
    5. }
    6. let item = Item {}
    7. io.writeLine("{item.value}")
    기대 출력종료 코드 0
    41
    
    $ topaz run main.tpz --compiler self · 대상 제품 5.21.3
    defaults.tpzUse an exported value in a record default플레이그라운드 열기 →
    1. export let visible: int = 0
    2. export let seed: int = 41
    3. let mut state: int = 42
    4. type Secret = int
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 41

    Export the nominal type used by an inferred public result

    링크
    main.tpzExport the nominal type used by an inferred public result플레이그라운드 열기 →
    1. import lib
    2. let value: lib.Hidden = lib.make()
    3. let observed: int = value.value
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzExport the nominal type used by an inferred public result플레이그라운드 열기 →
    1. export record Hidden { value: int }
    2. export function make() { Hidden { value: 7 } }
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    Export the nominal type used by a public binding

    링크
    main.tpzExport the nominal type used by a public binding플레이그라운드 열기 →
    1. import lib
    2. let value: lib.Hidden = lib.value
    3. let observed: int = value.value
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzExport the nominal type used by a public binding플레이그라운드 열기 →
    1. export record Hidden { value: int }
    2. export let value = Hidden { value: 7 }
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    A private alias of a public type is transparent

    링크
    main.tpzA private alias of a public type is transparent플레이그라운드 열기 →
    1. import lib
    2. let value: int = lib.count()
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzA private alias of a public type is transparent플레이그라운드 열기 →
    1. type Count = int
    2. export function count() -> Count { 1 }
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    Free calls, assignments, and loops in an entry

    링크
    helpers.tpzFree calls, assignments, and loops in an entry플레이그라운드 열기 →
    1. import std.io
    2. export let value: int = 1
    3. let mut count: int = 0
    4. io.writeLine("free")
    5. for item in ([1]) {
    6. count = count + item
    7. io.writeLine("loop")
    8. }
    9. io.writeLine("{count}")
    기대 출력종료 코드 0
    free
    loop
    1
    
    $ topaz run helpers.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. free
    2. loop
    3. 1

    The same source file imported

    링크
    main.tpzThe same source file imported플레이그라운드 열기 →
    1. import helpers
    2. import std.io
    3. io.writeLine("{helpers.value}")
    기대 출력종료 코드 0
    free
    loop
    1
    1
    
    $ topaz run main.tpz --compiler self · 대상 제품 5.21.3
    helpers.tpzThe same source file imported플레이그라운드 열기 →
    1. import std.io
    2. export let value: int = 1
    3. let mut count: int = 0
    4. io.writeLine("free")
    5. for item in ([1]) {
    6. count = count + item
    7. io.writeLine("loop")
    8. }
    9. io.writeLine("{count}")
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. free
    2. loop
    3. 1
    4. 1

    A diamond initializes once in ready-identity order

    링크
    main.tpzA diamond initializes once in ready-identity order플레이그라운드 열기 →
    1. import a
    2. import b
    3. import std.io
    4. io.writeLine("entry")
    기대 출력종료 코드 0
    shared
    b
    z
    a
    entry
    
    $ topaz run main.tpz --compiler self · 대상 제품 5.21.3
    a.tpzA diamond initializes once in ready-identity order플레이그라운드 열기 →
    1. import z
    2. import std.io
    3. export let value: int = {
    4. io.writeLine("a")
    5. z.value
    6. }
    b.tpzA diamond initializes once in ready-identity order플레이그라운드 열기 →
    1. import shared
    2. import std.io
    3. export let value: int = {
    4. io.writeLine("b")
    5. shared.value
    6. }
    z.tpzA diamond initializes once in ready-identity order플레이그라운드 열기 →
    1. import shared
    2. import std.io
    3. export let value: int = {
    4. io.writeLine("z")
    5. shared.value
    6. }
    shared.tpzA diamond initializes once in ready-identity order플레이그라운드 열기 →
    1. import std.io
    2. export let value: int = {
    3. io.writeLine("shared")
    4. 1
    5. }
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. shared
    2. b
    3. z
    4. a
    5. entry

    Reversing import lines preserves the initialization trace

    링크
    main.tpzReversing import lines preserves the initialization trace플레이그라운드 열기 →
    1. import std.io
    2. import b
    3. import a
    4. io.writeLine("entry")
    기대 출력종료 코드 0
    shared
    b
    z
    a
    entry
    
    $ topaz run main.tpz --compiler self · 대상 제품 5.21.3
    a.tpzReversing import lines preserves the initialization trace플레이그라운드 열기 →
    1. import z
    2. import std.io
    3. export let value: int = {
    4. io.writeLine("a")
    5. z.value
    6. }
    b.tpzReversing import lines preserves the initialization trace플레이그라운드 열기 →
    1. import shared
    2. import std.io
    3. export let value: int = {
    4. io.writeLine("b")
    5. shared.value
    6. }
    z.tpzReversing import lines preserves the initialization trace플레이그라운드 열기 →
    1. import shared
    2. import std.io
    3. export let value: int = {
    4. io.writeLine("z")
    5. shared.value
    6. }
    shared.tpzReversing import lines preserves the initialization trace플레이그라운드 열기 →
    1. import std.io
    2. export let value: int = {
    3. io.writeLine("shared")
    4. 1
    5. }
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. shared
    2. b
    3. z
    4. a
    5. entry

    A namespace import initializes an export-less module

    링크
    main.tpzA namespace import initializes an export-less module플레이그라운드 열기 →
    1. import setup
    2. import std.io
    3. io.writeLine("entry")
    기대 출력종료 코드 0
    setup
    entry
    
    $ topaz run main.tpz --compiler self · 대상 제품 5.21.3
    setup.tpzA namespace import initializes an export-less module플레이그라운드 열기 →
    1. import std.io
    2. let initialized: int = {
    3. io.writeLine("setup")
    4. 1
    5. }
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. setup
    2. entry

    Removing the back edge gives dependency-first effects

    링크
    main.tpzRemoving the back edge gives dependency-first effects플레이그라운드 열기 →
    1. import first
    2. import std.io
    3. io.writeLine("entry")
    기대 출력종료 코드 0
    second
    first
    entry
    
    $ topaz run main.tpz --compiler self · 대상 제품 5.21.3
    first.tpzRemoving the back edge gives dependency-first effects플레이그라운드 열기 →
    1. import second
    2. import std.io
    3. export let one: int = {
    4. io.writeLine("first")
    5. 1
    6. }
    second.tpzRemoving the back edge gives dependency-first effects플레이그라운드 열기 →
    1. import std.io
    2. export let two: int = {
    3. io.writeLine("second")
    4. 2
    5. }
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. second
    2. first
    3. entry

    Move the dependency before the initializer

    링크
    main.tpzMove the dependency before the initializer플레이그라운드 열기 →
    1. let second = 1
    2. export let first = second
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    The same source-order repair in an imported file

    링크
    main.tpzThe same source-order repair in an imported file플레이그라운드 열기 →
    1. import lib
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzThe same source-order repair in an imported file플레이그라운드 열기 →
    1. let second = 1
    2. export let first = second
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    Repairing the fault completes the remaining initialization

    링크
    main.tpzRepairing the fault completes the remaining initialization플레이그라운드 열기 →
    1. import a
    2. import b
    3. import c
    4. import std.io
    5. io.writeLine("entry")
    기대 출력종료 코드 0
    a
    b-before
    b-after
    c
    entry
    
    $ topaz run main.tpz --compiler self · 대상 제품 5.21.3
    a.tpzRepairing the fault completes the remaining initialization플레이그라운드 열기 →
    1. import std.io
    2. export let value: int = {
    3. io.writeLine("a")
    4. 1
    5. }
    b.tpzRepairing the fault completes the remaining initialization플레이그라운드 열기 →
    1. import std.io
    2. function readAt(index: int) -> int {
    3. let values = [10]
    4. values[index]
    5. }
    6. export let value: int = {
    7. io.writeLine("b-before")
    8. readAt(0)
    9. }
    10. export let after: int = {
    11. io.writeLine("b-after")
    12. 1
    13. }
    c.tpzRepairing the fault completes the remaining initialization플레이그라운드 열기 →
    1. import std.io
    2. export let value: int = {
    3. io.writeLine("c")
    4. 1
    5. }
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. a
    2. b-before
    3. b-after
    4. c
    5. entry

    Omit the namespace alias to keep its default name

    링크
    main.tpzOmit the namespace alias to keep its default name플레이그라운드 열기 →
    1. import lib
    2. let result: int = lib.value
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzOmit the namespace alias to keep its default name플레이그라운드 열기 →
    1. export let value: int = 1
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    Omit the selected alias to keep its source name

    링크
    main.tpzOmit the selected alias to keep its source name플레이그라운드 열기 →
    1. import lib { value }
    2. let result: int = value
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzOmit the selected alias to keep its source name플레이그라운드 열기 →
    1. export let value: int = 1
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    Export every record binding after one initializer

    링크
    main.tpzExport every record binding after one initializer플레이그라운드 열기 →
    1. import lib
    2. import std.io { writeLine }
    3. writeLine("{lib.first}")
    4. writeLine("{lib.second}")
    기대 출력종료 코드 0
    init
    10
    20
    
    $ topaz run main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzExport every record binding after one initializer플레이그라운드 열기 →
    1. import std.io { writeLine }
    2. function make() -> { first: int, second: int } {
    3. writeLine("init")
    4. { first: 10, second: 20 }
    5. }
    6. export let { first: first, second: second } = make()
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. init
    2. 10
    3. 20

    An outer pattern annotation supplies each public binding type

    링크
    main.tpzAn outer pattern annotation supplies each public binding type플레이그라운드 열기 →
    1. import lib { count, label }
    2. let number: int = count
    3. let text: string = label
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzAn outer pattern annotation supplies each public binding type플레이그라운드 열기 →
    1. export let { nested: { count: count }, label: label }: { nested: { count: int }, label: string } = { nested: { count: 4 }, label: "four" }
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    Export names from an ordinary nominal record pattern

    링크
    main.tpzExport names from an ordinary nominal record pattern플레이그라운드 열기 →
    1. import lib
    2. import std.io { writeLine }
    3. writeLine("{lib.first + lib.second}")
    기대 출력종료 코드 0
    42
    
    $ topaz run main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzExport names from an ordinary nominal record pattern플레이그라운드 열기 →
    1. record Pair { first: int, second: int }
    2. export let Pair { first: first, second: second } = Pair { first: 20, second: 22 }
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 42

    A mutable local leaves the exported array unchanged

    링크
    main.tpzA mutable local leaves the exported array unchanged플레이그라운드 열기 →
    1. import std.io
    2. import helpers { items }
    3. let mut local = items
    4. local.push(3)
    5. io.writeLine("{items.length}:{local.length}")
    기대 출력종료 코드 0
    2:3
    
    $ topaz run main.tpz --compiler self · 대상 제품 5.21.3
    helpers.tpzA mutable local leaves the exported array unchanged플레이그라운드 열기 →
    1. export let items = [1, 2]
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 2:3

    Rejected forms and boundaries

    링크

    The following files demonstrate rejected imports and exports. Compare their commands with the accepted examples above.

    Use is not an import item

    링크
    main.tpzUse is not an import item플레이그라운드 열기 →
    1. use helpers
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ2008]: `use` is reserved and unused; did you mean `import`?
     --> main.tpz:1:1
      |
    1 | use helpers
      | ^^^
    
    main.tpz: 1 diagnostic
    
    $ topaz check main.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    helpers.tpzUse is not an import item플레이그라운드 열기 →
    1. export function double(value: int) -> int {
    2. value + value
    3. }
    4. export let increment: int = 1
    5. let secret: int = 99
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ2008]: `use` is reserved and unused; did you mean `import`?
    2. --> main.tpz:1:1
    3. |
    4. 1 | use helpers
    5. | ^^^
    6. main.tpz: 1 diagnostic
    • 통과 · expected nonzero; observed 1
    • 통과 · stdout matches the authored expectation
    • 통과 · checking TPZ2008; cause reserved-use-item; primary location asserted; additional diagnostics allow

    A string is not a module path

    링크
    main.tpzA string is not a module path플레이그라운드 열기 →
    1. import "helpers"
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ2008]: string and template module paths are reserved and unused; module paths are dotted identifiers
     --> main.tpz:1:1
      |
    1 | import "helpers"
      | ^^^^^^
    
    main.tpz: 1 diagnostic
    
    $ topaz check main.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    helpers.tpzA string is not a module path플레이그라운드 열기 →
    1. export function double(value: int) -> int {
    2. value + value
    3. }
    4. export let increment: int = 1
    5. let secret: int = 99
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ2008]: string and template module paths are reserved and unused; module paths are dotted identifiers
    2. --> main.tpz:1:1
    3. |
    4. 1 | import "helpers"
    5. | ^^^^^^
    6. main.tpz: 1 diagnostic
    • 통과 · expected nonzero; observed 1
    • 통과 · stdout matches the authored expectation
    • 통과 · checking TPZ2008; cause reserved-string-module-path; primary location asserted; additional diagnostics allow

    Export lists are rejected

    링크
    main.tpzExport lists are rejected플레이그라운드 열기 →
    1. function double(value: int) -> int {
    2. value + value
    3. }
    4. export { double }
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ2009]: export lists are invalid syntax; put `export` on each public declaration
     --> main.tpz:4:1
      |
    4 | export { double }
      | ^^^^^^
    
    main.tpz: 1 diagnostic
    
    $ topaz check main.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ2009]: export lists are invalid syntax; put `export` on each public declaration
    2. --> main.tpz:4:1
    3. |
    4. 4 | export { double }
    5. | ^^^^^^
    6. main.tpz: 1 diagnostic
    • 통과 · expected nonzero; observed 1
    • 통과 · stdout matches the authored expectation
    • 통과 · checking TPZ2009; cause rejected-export-list; primary location asserted; additional diagnostics allow

    Export import is rejected

    링크
    main.tpzExport import is rejected플레이그라운드 열기 →
    1. export import helpers
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ2009]: re-export syntax does not exist (`export import ...` is rejected)
     --> main.tpz:1:1
      |
    1 | export import helpers
      | ^^^^^^
    
    main.tpz: 1 diagnostic
    
    $ topaz check main.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    helpers.tpzExport import is rejected플레이그라운드 열기 →
    1. export function double(value: int) -> int {
    2. value + value
    3. }
    4. export let increment: int = 1
    5. let secret: int = 99
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ2009]: re-export syntax does not exist (`export import ...` is rejected)
    2. --> main.tpz:1:1
    3. |
    4. 1 | export import helpers
    5. | ^^^^^^
    6. main.tpz: 1 diagnostic
    • 통과 · expected nonzero; observed 1
    • 통과 · stdout matches the authored expectation
    • 통과 · checking TPZ2009; cause rejected-reexport; primary location asserted; additional diagnostics allow

    A namespace alias and selection do not compose

    링크
    main.tpzA namespace alias and selection do not compose플레이그라운드 열기 →
    1. import helpers as names { double }
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ2009]: a namespace alias and a selection list do not compose (`import m as ns { x }` is invalid syntax)
     --> main.tpz:1:25
      |
    1 | import helpers as names { double }
      |                         ^
    
    main.tpz: 1 diagnostic
    
    $ topaz check main.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    helpers.tpzA namespace alias and selection do not compose플레이그라운드 열기 →
    1. export function double(value: int) -> int {
    2. value + value
    3. }
    4. export let increment: int = 1
    5. let secret: int = 99
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    • TPZ2009 →

      namespace-alias-with-selection at main.tpz:1:25

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ2009]: a namespace alias and a selection list do not compose (`import m as ns { x }` is invalid syntax)
    2. --> main.tpz:1:25
    3. |
    4. 1 | import helpers as names { double }
    5. | ^
    6. main.tpz: 1 diagnostic
    • 통과 · expected nonzero; observed 1
    • 통과 · stdout matches the authored expectation
    • 통과 · checking TPZ2009; cause namespace-alias-with-selection; primary location asserted; additional diagnostics allow

    Imports precede other items

    링크
    main.tpzImports precede other items플레이그라운드 열기 →
    1. let before: int = 0
    2. import helpers
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ2010]: imports form a prologue: every `import` precedes all other top-level items
     --> main.tpz:2:1
      |
    2 | import helpers
      | ^^^^^^^^^^^^^^
    
    main.tpz: 1 diagnostic
    
    $ topaz check main.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    helpers.tpzImports precede other items플레이그라운드 열기 →
    1. export function double(value: int) -> int {
    2. value + value
    3. }
    4. export let increment: int = 1
    5. let secret: int = 99
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ2010]: imports form a prologue: every `import` precedes all other top-level items
    2. --> main.tpz:2:1
    3. |
    4. 2 | import helpers
    5. | ^^^^^^^^^^^^^^
    6. main.tpz: 1 diagnostic
    • 통과 · expected nonzero; observed 1
    • 통과 · stdout matches the authored expectation
    • 통과 · checking TPZ2010; cause import-after-prologue; primary location asserted; additional diagnostics allow

    A selected name must be exported

    링크
    main.tpzA selected name must be exported플레이그라운드 열기 →
    1. import helpers { secret }
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ3009]: `secret` is not exported by `helpers`
     --> main.tpz:1:18
      |
    1 | import helpers { secret }
      |                  ^^^^^^
    
    main.tpz: 1 diagnostic
    
    $ topaz check main.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    helpers.tpzA selected name must be exported플레이그라운드 열기 →
    1. export function double(value: int) -> int {
    2. value + value
    3. }
    4. export let increment: int = 1
    5. let secret: int = 99
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ3009]: `secret` is not exported by `helpers`
    2. --> main.tpz:1:18
    3. |
    4. 1 | import helpers { secret }
    5. | ^^^^^^
    6. main.tpz: 1 diagnostic
    • 통과 · expected nonzero; observed 1
    • 통과 · stdout matches the authored expectation
    • 통과 · checking TPZ3009; cause selected-name-not-exported; primary location asserted; additional diagnostics allow

    The target exports double and increment. The intended rejection concerns the private secret binding, not an empty export table.

    Exporting a mutable let is rejected

    링크
    main.tpzExporting a mutable let is rejected플레이그라운드 열기 →
    1. export let mut count: int = 0
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ3011]: `export let mut` is a static error: exported bindings are immutable views
     --> main.tpz:1:16
      |
    1 | export let mut count: int = 0
      |                ^^^^^
    
    main.tpz: 1 diagnostic
    
    $ topaz check main.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ3011]: `export let mut` is a static error: exported bindings are immutable views
    2. --> main.tpz:1:16
    3. |
    4. 1 | export let mut count: int = 0
    5. | ^^^^^
    6. main.tpz: 1 diagnostic
    • 통과 · expected nonzero; observed 1
    • 통과 · stdout matches the authored expectation
    • 통과 · checking TPZ3011; cause mutable-let-export; primary location asserted; additional diagnostics allow

    A record default cannot read a private mutable value

    링크
    main.tpzA record default cannot read a private mutable value플레이그라운드 열기 →
    1. import defaults
    2. record Item {
    3. value: int = defaults.state
    4. }
    5. let item = Item {}
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    defaults.tpzA record default cannot read a private mutable value플레이그라운드 열기 →
    1. export let visible: int = 0
    2. let seed: int = 41
    3. let mut state: int = 42
    4. type Secret = int
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3009 →

      record-default-private-mutable-member at main.tpz:3:27

    A default value does not grant access to a private type

    링크
    main.tpzA default value does not grant access to a private type플레이그라운드 열기 →
    1. import defaults
    2. record Item {
    3. value: int = {
    4. let saved: defaults.Secret = 1
    5. saved
    6. }
    7. }
    8. let item = Item {}
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    defaults.tpzA default value does not grant access to a private type플레이그라운드 열기 →
    1. export let visible: int = 0
    2. let seed: int = 41
    3. let mut state: int = 42
    4. type Secret = int
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3009 →

      record-default-private-type-member at main.tpz:4:29

    The private value remains inaccessible outside a default

    링크
    main.tpzThe private value remains inaccessible outside a default플레이그라운드 열기 →
    1. import defaults
    2. let value: int = defaults.seed
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    defaults.tpzThe private value remains inaccessible outside a default플레이그라운드 열기 →
    1. export let visible: int = 0
    2. let seed: int = 41
    3. let mut state: int = 42
    4. type Secret = int
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3009 →

      namespace-private-let-outside-default at main.tpz:2:27

    Reject a private value in a record default

    링크
    main.tpzReject a private value in a record default플레이그라운드 열기 →
    1. import std.io
    2. import defaults
    3. record Item {
    4. value: int = defaults.seed
    5. }
    6. let item = Item {}
    7. io.writeLine("{item.value}")
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    defaults.tpzReject a private value in a record default플레이그라운드 열기 →
    1. export let visible: int = 0
    2. let seed: int = 41
    3. let mut state: int = 42
    4. type Secret = int
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3009 →

      record-default-private-immutable-member at main.tpz:4:27

    An explicit public result cannot expose a private nominal type

    링크
    main.tpzAn explicit public result cannot expose a private nominal type플레이그라운드 열기 →
    1. import lib
    2. let value = lib.make()
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzAn explicit public result cannot expose a private nominal type플레이그라운드 열기 →
    1. record Hidden { value: int }
    2. export function make() -> Hidden { Hidden { value: 7 } }
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3014 →

      modules-public-private-nominal at lib.tpz:2:27

    An inferred public result obeys the same visibility rule

    링크
    main.tpzAn inferred public result obeys the same visibility rule플레이그라운드 열기 →
    1. import lib
    2. let value = lib.make()
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzAn inferred public result obeys the same visibility rule플레이그라운드 열기 →
    1. record Hidden { value: int }
    2. export function make() { Hidden { value: 7 } }
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3014 →

      modules-public-private-nominal at lib.tpz:2:17

    A collection result cannot hide a private element type

    링크
    main.tpzA collection result cannot hide a private element type플레이그라운드 열기 →
    1. import lib
    2. let value = lib.make()
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzA collection result cannot hide a private element type플레이그라운드 열기 →
    1. record Hidden { value: int }
    2. export function make() { [Hidden { value: 7 }] }
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3014 →

      modules-public-private-nominal at lib.tpz:2:17

    An annotated exported binding cannot expose a private nominal type

    링크
    main.tpzAn annotated exported binding cannot expose a private nominal type플레이그라운드 열기 →
    1. import lib
    2. let value = lib.value
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzAn annotated exported binding cannot expose a private nominal type플레이그라운드 열기 →
    1. record Hidden { value: int }
    2. export let value: Hidden = Hidden { value: 7 }
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3014 →

      modules-public-private-nominal at lib.tpz:2:19

    An inferred exported binding cannot expose a private nominal type

    링크
    main.tpzAn inferred exported binding cannot expose a private nominal type플레이그라운드 열기 →
    1. import lib
    2. let value = lib.value
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzAn inferred exported binding cannot expose a private nominal type플레이그라운드 열기 →
    1. record Hidden { value: int }
    2. export let value = Hidden { value: 7 }
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3014 →

      modules-public-private-nominal at lib.tpz:2:12

    An alias expansion cannot hide a private nominal result

    링크
    main.tpzAn alias expansion cannot hide a private nominal result플레이그라운드 열기 →
    1. import lib
    2. let value = lib.make()
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzAn alias expansion cannot hide a private nominal result플레이그라운드 열기 →
    1. record Hidden { value: int }
    2. type Alias = Hidden
    3. export function make() -> Alias { Hidden { value: 7 } }
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3014 →

      modules-public-private-nominal at lib.tpz:3:27

    An empty namespace still has no selectable member

    링크
    main.tpzAn empty namespace still has no selectable member플레이그라운드 열기 →
    1. import setup { missing }
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    setup.tpzAn empty namespace still has no selectable member플레이그라운드 열기 →
    1. let value: int = 1
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    An import cycle is rejected before initialization

    링크
    main.tpzAn import cycle is rejected before initialization플레이그라운드 열기 →
    1. import first
    2. import std.io
    3. io.writeLine("entry")
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run main.tpz --compiler self · 대상 제품 5.21.3
    first.tpzAn import cycle is rejected before initialization플레이그라운드 열기 →
    1. import second
    2. import std.io
    3. export let one: int = {
    4. io.writeLine("first")
    5. 1
    6. }
    second.tpzAn import cycle is rejected before initialization플레이그라운드 열기 →
    1. import first
    2. import std.io
    3. export let two: int = {
    4. io.writeLine("second")
    5. 2
    6. }
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    An entry initializer cannot read a later binding

    링크
    main.tpzAn entry initializer cannot read a later binding플레이그라운드 열기 →
    1. export let first = second
    2. let second = 1
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3018 →

      module-initializer-not-ready at main.tpz:1:20

    The same early read is rejected in an imported file

    링크
    main.tpzThe same early read is rejected in an imported file플레이그라운드 열기 →
    1. import lib
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzThe same early read is rejected in an imported file플레이그라운드 열기 →
    1. export let first = second
    2. let second = 1
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3018 →

      module-initializer-not-ready at lib.tpz:1:20

    A fault preserves earlier output and stops remaining initialization

    링크
    main.tpzA fault preserves earlier output and stops remaining initialization플레이그라운드 열기 →
    1. import a
    2. import b
    3. import c
    4. import std.io
    5. io.writeLine("entry")
    기대 출력0이 아닌 종료 코드
    a
    b-before
    
    $ topaz run main.tpz --compiler self · 대상 제품 5.21.3
    a.tpzA fault preserves earlier output and stops remaining initialization플레이그라운드 열기 →
    1. import std.io
    2. export let value: int = {
    3. io.writeLine("a")
    4. 1
    5. }
    b.tpzA fault preserves earlier output and stops remaining initialization플레이그라운드 열기 →
    1. import std.io
    2. function readAt(index: int) -> int {
    3. let values = [10]
    4. values[index]
    5. }
    6. export let value: int = {
    7. io.writeLine("b-before")
    8. readAt(1)
    9. }
    10. export let after: int = {
    11. io.writeLine("b-after")
    12. 1
    13. }
    c.tpzA fault preserves earlier output and stops remaining initialization플레이그라운드 열기 →
    1. import std.io
    2. export let value: int = {
    3. io.writeLine("c")
    4. 1
    5. }
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    기대 표준 출력
    1. a
    2. b-before

    Reject a namespace alias repeating its default name

    링크
    main.tpzReject a namespace alias repeating its default name플레이그라운드 열기 →
    1. import lib as lib
    2. let result: int = lib.value
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzReject a namespace alias repeating its default name플레이그라운드 열기 →
    1. export let value: int = 1
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    This rejection is the intended TPZ2009/parse contract for a redundant alias. The reviewed SELF parser currently accepts the form. The limitation permits only the expected exit and diagnostic assertions to fail; the expected source location is the alias identifier.

    Reject a selected alias repeating its source name

    링크
    main.tpzReject a selected alias repeating its source name플레이그라운드 열기 →
    1. import lib { value as value }
    2. let result: int = value
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzReject a selected alias repeating its source name플레이그라운드 열기 →
    1. export let value: int = 1
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    This rejection is the intended TPZ2009/parse contract for a redundant alias. The reviewed SELF parser currently accepts the form. The limitation permits only the expected exit and diagnostic assertions to fail; the expected source location is the alias identifier.

    Use plain let when a pattern publishes no binding

    링크
    main.tpzUse plain let when a pattern publishes no binding플레이그라운드 열기 →
    1. export let _ = 1
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    Export preserves the ordinary refutable-let rejection

    링크
    main.tpzExport preserves the ordinary refutable-let rejection플레이그라운드 열기 →
    1. let maybe: Option<int> = None()
    2. export let Some(value) = maybe
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5026 →

      diagnostics-refutable-let-pattern at main.tpz:2:12

    Each bound name must have a public resolved type

    링크
    main.tpzEach bound name must have a public resolved type플레이그라운드 열기 →
    1. import lib
    2. let observed = lib.count
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self --format json · 대상 제품 5.21.3
    lib.tpzEach bound name must have a public resolved type플레이그라운드 열기 →
    1. record Hidden { value: int }
    2. export let { item: item, count: count } = { item: Hidden { value: 1 }, count: 2 }
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3014 →

      modules-public-private-nominal at lib.tpz:2:20

    An imported array has an immutable root

    링크
    main.tpzAn imported array has an immutable root플레이그라운드 열기 →
    1. import helpers { items }
    2. items[0] = 9
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --compiler self · 대상 제품 5.21.3
    helpers.tpzAn imported array has an immutable root플레이그라운드 열기 →
    1. export let items = [1, 2]
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5003 →

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

    Pending contracts

    링크

    Related contracts

    링크

    Functions and generics →

    check →

    Functions and generics owns callable declarations, calls, and exported protocol-bound restrictions. The check command owns invocation, selected entry and root, output channels, and exit status. Module visibility does not redefine those contracts.

    Import after non-import item →

    Malformed import list →

    Rejected module-adjacent form →

    Duplicate import →

    Invalid exported let pattern →

    Mutable export is rejected →

    Name is not exported →

    Assignment to imported binding →

    Private type in exported surface →

    Reserved module form →

    Import cycle →

    Initializer reads a later binding →

    Index out of bounds →

    Refutable let pattern →

    TPZ5524 →

    Immutable binding mutation →

    메뉴

    다운로드 →