# `RustQ.Meta.Lower.Stdlib.Lowering`
[🔗](https://github.com/elixir-crab/rustq/blob/v1.0.0-rc.19/lib/rustq/meta/lower/stdlib/lowering.ex#L1)

The behaviour of a module lowering one Elixir standard-library module, and the helpers such
a module lowers and types its arguments with.

`RustQ.Meta.Lower.Stdlib` dispatches a call to `Enum` to `RustQ.Meta.Lower.Enum`, a call to
`Map` to `RustQ.Meta.Lower.Map`, and so on: the module named after the Elixir module, when
it implements this behaviour. `use` this module to implement it and import the helpers:

    defmodule RustQ.Meta.Lower.List do
      use RustQ.Meta.Lower.Stdlib.Lowering

      @impl true
      def lower(%Call{function: :first, args: [list]}, %Context{} = context),
        do: {:ok, list |> lowered(context) |> A.method(:into_iter) |> A.method(:next)}
    end

A lowering returns `:unsupported` for a call it does not lower, and `RustQ.Meta.Lower.Stdlib`
reports it.

# `lower`

```elixir
@callback lower(RustQ.Meta.Core.Call.t(), RustQ.Meta.Lower.Stdlib.Lowering.Context.t()) ::
  {:ok, RustQ.Rust.AST.expr()} | :unsupported
```

Lowers `call`, or returns `:unsupported` for a call this module does not lower.

# `synth`

```elixir
@callback synth(
  RustQ.Meta.Core.Call.t(),
  RustQ.Meta.Lower.Stdlib.Lowering.TypeContext.t()
) ::
  {:ok, RustQ.Meta.Type.t()} | :unsupported
```

Types `call`, or returns `:unsupported` for a call this module does not type.

# `capture`

```elixir
@spec capture(Macro.t(), RustQ.Meta.Lower.Stdlib.Lowering.Context.t()) ::
  RustQ.Rust.AST.expr()
```

A captured named function, as the Rust path of that function.

# `closure`

```elixir
@spec closure([Macro.t()], Macro.t(), RustQ.Meta.Lower.Stdlib.Lowering.Context.t()) ::
  RustQ.Rust.AST.expr()
```

A closure taking `args` and returning `body`, lowered.

# `closure`

```elixir
@spec closure(
  [Macro.t()],
  Macro.t(),
  RustQ.Meta.Type.t() | nil,
  RustQ.Meta.Lower.Stdlib.Lowering.Context.t()
) :: RustQ.Rust.AST.expr()
```

A closure taking `args` and returning `body` as a value of `returns`, lowered.

# `closure_arg`

```elixir
@spec closure_arg(Macro.t()) :: atom() | RustQ.Rust.AST.pat()
```

A closure argument, as a Rust closure argument.

# `closure_body`

```elixir
@spec closure_body(
  Macro.t(),
  RustQ.Meta.Type.t() | nil,
  RustQ.Meta.Lower.Stdlib.Lowering.Context.t()
) ::
  RustQ.Rust.AST.expr()
```

A closure's `body`, lowered to return a value of `returns`.

# `evaluated_constant`

```elixir
@spec evaluated_constant(
  Macro.t(),
  term(),
  RustQ.Meta.Lower.Stdlib.Lowering.Context.t()
) ::
  {:ok, RustQ.Rust.AST.expr()}
```

`argument` evaluated for its effects, then the constant `value`.

# `in_use?`

```elixir
@spec in_use?(Macro.t(), RustQ.Meta.Lower.Stdlib.Lowering.Context.t()) :: boolean()
```

Whether `collection` is still in use after this use of it; see `RustQ.Meta.Ownership`.

# `integer_count`

```elixir
@spec integer_count(
  RustQ.Rust.AST.expr(),
  RustQ.Meta.Lower.Stdlib.Lowering.Context.t()
) ::
  RustQ.Rust.AST.expr()
```

A Rust count as Elixir's integer, an `i64`, unless the call is expected to produce a `usize`.

# `lowered`

```elixir
@spec lowered(Macro.t(), RustQ.Meta.Lower.Stdlib.Lowering.Context.t()) ::
  RustQ.Rust.AST.expr()
```

`expression`, lowered.

# `lowered`

```elixir
@spec lowered(
  Macro.t(),
  RustQ.Meta.Type.t() | nil,
  RustQ.Meta.Lower.Stdlib.Lowering.Context.t()
) ::
  RustQ.Rust.AST.expr()
```

`expression`, lowered to produce a value of `expected`.

# `lowering?`

```elixir
@spec lowering?(module()) :: boolean()
```

Whether `module` lowers an Elixir standard-library module.

# `nonnegative_count`

```elixir
@spec nonnegative_count(Macro.t(), RustQ.Meta.Lower.Stdlib.Lowering.Context.t()) ::
  {:ok, RustQ.Rust.AST.expr()} | :unsupported
```

`count` as a `usize`, when it is a literal or unsigned count that cannot be negative.

# `operand`

```elixir
@spec operand(Macro.t(), RustQ.Meta.Lower.Stdlib.Lowering.Context.t()) ::
  RustQ.Rust.AST.expr()
```

`expression`, lowered as an operand: a fallible one propagates its error with `?`.

# `shape_type`

```elixir
@spec shape_type(RustQ.Meta.Type.t() | nil) :: RustQ.Meta.Type.t() | nil
```

The type a call shapes its value as: a fallible call's success type, and others' own.

# `type_of`

```elixir
@spec type_of(
  Macro.t(),
  RustQ.Meta.Lower.Stdlib.Lowering.Context.t()
  | RustQ.Meta.Lower.Stdlib.Lowering.TypeContext.t()
) :: RustQ.Meta.Type.t() | nil
```

The type of `expression`, or nil when it is not known.

# `type_with_vars`

```elixir
@spec type_with_vars(
  Macro.t(),
  %{optional(atom()) =&gt; RustQ.Meta.Type.t()},
  RustQ.Meta.Lower.Stdlib.Lowering.TypeContext.t()
) :: RustQ.Meta.Type.t() | nil
```

The type of `expression` where `vars` are bound to the given types.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
