# V1006 private_item

URL: /docs/errors/V1006
Markdown: /docs/errors/V1006.md

> The item exists but this module cannot use it: it is not pub, or it is a constructor or field of a pub opaque type, which only the declaring module may use (design §9, §17.10).

An error from the `resolve` phase. `sakura explain V1006` prints this explanation offline.

The item exists but this module cannot use it: it is not `pub`, or it is a constructor or field
of a `pub opaque` type, which only the declaring module may use (design §9, §17.10). Mark a
private item `pub` (an interface change) or use a public API; build and read an opaque value
through the functions its module exports.

Wrong:

```sakura
fn make() -> Html { Html("<b>not escaped</b>") }
```

Fixed:

```sakura
fn make() -> Html { Html.text("<b>escaped</b>") }
```

## Wrong program [#wrong-program]

[`compiler/tests/ui/V1006_opaque_constructor.sakura`](https://github.com/icantcodefyi/sakuralang/blob/master/compiler/tests/ui/V1006_opaque_constructor.sakura), which the compiler's ui suite runs through `sakura check`:

```sakura
import std/html.{Html}

fn forged() -> Html { Html("<script>evil()</script>") }
```

`sakura check --json` reports this record (pretty-printed; `$DIR` is the fixture's directory):

```json
{
  "schema_version": "1.0",
  "kind": "diagnostic",
  "id": "d:c155d42c6fc1dcff",
  "code": "V1006",
  "severity": "error",
  "phase": "resolve",
  "message": "`Html` is opaque: its constructors and fields are private to module `std/html`; create one with `Html.text(…)`",
  "snapshot": "sha256:$SNAPSHOT",
  "symbol_id": "main::V1006_opaque_constructor::forged",
  "spans": [
    {
      "uri": "file://$DIR/V1006_opaque_constructor.sakura",
      "content_hash": "sha256:211177718e6c3b71682268c70462cfd8072f349bdf97e6e7fd211c4f3a7726f5",
      "start_byte": 80,
      "end_byte": 84,
      "role": "primary"
    },
    {
      "uri": "sakura:///std/html.sakura",
      "content_hash": "sha256:c1ae97f2077f44255567e95a767863404dbc4f7feea60cdcff0ed4e48a4c69aa",
      "start_byte": 413,
      "end_byte": 417,
      "role": "definition",
      "label": "declared `pub opaque` here"
    }
  ],
  "related_ids": [],
  "expected": null,
  "actual": null,
  "obligation": null,
  "counterexample": null,
  "explanation_uri": "sakura://explain/V1006",
  "fixes": []
}
```

More fixtures for this code: [`compiler/tests/ui/V1006_opaque_field.sakura`](https://github.com/icantcodefyi/sakuralang/blob/master/compiler/tests/ui/V1006_opaque_field.sakura), [`compiler/tests/ui/V1006_private_item.sakura`](https://github.com/icantcodefyi/sakuralang/blob/master/compiler/tests/ui/V1006_private_item.sakura).

## Fixed program [#fixed-program]

[`compiler/tests/ui/V1006_opaque_constructor.fixed.sakura`](https://github.com/icantcodefyi/sakuralang/blob/master/compiler/tests/ui/V1006_opaque_constructor.fixed.sakura), which `sakura check` accepts with no diagnostics:

```sakura
import std/html.{Html}

fn escaped() -> Html { Html.text("<script>evil()</script>") }
```
