Skip to content

diagnostics

Centralize the small helpers that lowering uses to raise structured diagnostic exceptions instead of ad hoc Exception strings.

Functions:

lowered_value_type_name

lowered_value_type_name(value: Value | None) -> str
Source code in src/irx/builder/diagnostics.py
46
47
48
49
50
51
52
53
54
55
56
57
58
@typechecked
def lowered_value_type_name(value: ir.Value | None) -> str:
    """
    title: Return one lowered LLVM value type name.
    parameters:
      value:
        type: ir.Value | None
    returns:
      type: str
    """
    if value is None:
        return "<missing>"
    return str(value.type)

raise_lowering_error

raise_lowering_error(
    message: str,
    *,
    code: str,
    node: AST | None = None,
    notes: tuple[str, ...] = (),
    hint: str | None = None,
    cause: Exception | None = None,
) -> NoReturn
Source code in src/irx/builder/diagnostics.py
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
@typechecked
def raise_lowering_error(
    message: str,
    *,
    code: str,
    node: astx.AST | None = None,
    notes: tuple[str, ...] = (),
    hint: str | None = None,
    cause: Exception | None = None,
) -> NoReturn:
    """
    title: Raise one user-facing lowering diagnostic.
    parameters:
      message:
        type: str
      code:
        type: str
      node:
        type: astx.AST | None
      notes:
        type: tuple[str, Ellipsis]
      hint:
        type: str | None
      cause:
        type: Exception | None
    returns:
      type: NoReturn
    """
    raise LoweringError(
        Diagnostic(
            message=message,
            node=node,
            module_key=get_node_module_key(node),
            code=code,
            phase="lowering",
            notes=notes,
            hint=hint,
            cause=cause,
        )
    )

raise_lowering_internal_error

raise_lowering_internal_error(
    message: str,
    *,
    node: AST | None = None,
    code: str = LOWERING_MISSING_SEMANTIC_METADATA,
    notes: tuple[str, ...] = (),
    hint: str | None = None,
    cause: Exception | None = None,
) -> NoReturn
Source code in src/irx/builder/diagnostics.py
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
@typechecked
def raise_lowering_internal_error(
    message: str,
    *,
    node: astx.AST | None = None,
    code: str = DiagnosticCodes.LOWERING_MISSING_SEMANTIC_METADATA,
    notes: tuple[str, ...] = (),
    hint: str | None = None,
    cause: Exception | None = None,
) -> NoReturn:
    """
    title: Raise one internal lowering consistency diagnostic.
    parameters:
      message:
        type: str
      node:
        type: astx.AST | None
      code:
        type: str
      notes:
        type: tuple[str, Ellipsis]
      hint:
        type: str | None
      cause:
        type: Exception | None
    returns:
      type: NoReturn
    """
    raise_lowering_error(
        f"internal compiler error: {message}",
        code=code,
        node=node,
        notes=notes,
        hint=hint,
        cause=cause,
    )

require_lowered_value

require_lowered_value(
    value: Value | None, *, node: AST, context: str
) -> Value
Source code in src/irx/builder/diagnostics.py
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
@typechecked
def require_lowered_value(
    value: ir.Value | None,
    *,
    node: astx.AST,
    context: str,
) -> ir.Value:
    """
    title: Require one lowered LLVM value during lowering.
    parameters:
      value:
        type: ir.Value | None
      node:
        type: astx.AST
      context:
        type: str
    returns:
      type: ir.Value
    """
    if value is None:
        raise_lowering_internal_error(
            f"{context} did not lower to a value",
            node=node,
            notes=(f"semantic type: {resolved_ast_type_name(node)}",),
        )
    return value

require_semantic_metadata

require_semantic_metadata(
    value: T | None,
    *,
    node: AST,
    metadata: str,
    context: str,
) -> T
Source code in src/irx/builder/diagnostics.py
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
@typechecked
def require_semantic_metadata(
    value: T | None,
    *,
    node: astx.AST,
    metadata: str,
    context: str,
) -> T:
    """
    title: Require one semantic sidecar field during lowering.
    parameters:
      value:
        type: T | None
      node:
        type: astx.AST
      metadata:
        type: str
      context:
        type: str
    returns:
      type: T
    """
    if value is None:
        raise_lowering_internal_error(
            f"missing {metadata} metadata during {context}",
            node=node,
            notes=(f"semantic type: {resolved_ast_type_name(node)}",),
        )
    return value

resolved_ast_type_name

resolved_ast_type_name(node: AST | None) -> str
Source code in src/irx/builder/diagnostics.py
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@typechecked
def resolved_ast_type_name(node: astx.AST | None) -> str:
    """
    title: Return one node's best-effort semantic type name.
    parameters:
      node:
        type: astx.AST | None
    returns:
      type: str
    """
    if node is None:
        return "<unknown>"
    semantic = getattr(node, "semantic", None)
    resolved_type = getattr(semantic, "resolved_type", None)
    if isinstance(resolved_type, astx.DataType):
        return display_type_name(resolved_type)
    return display_type_name(getattr(node, "type_", None))