Skip to content

Emit Hole for Composite return values assigned to Any#727

Merged
tautschnig merged 7 commits intomainfrom
tautschnig/coerce-composite
Apr 4, 2026
Merged

Emit Hole for Composite return values assigned to Any#727
tautschnig merged 7 commits intomainfrom
tautschnig/coerce-composite

Conversation

@tautschnig
Copy link
Copy Markdown
Contributor

@tautschnig tautschnig commented Apr 1, 2026

Problem

When a Python function returns a Composite-typed value (e.g., a service client) but the Laurel return variable LaurelResult has type Any, Core type checking fails with "Impossible to unify Any with Composite".

Approach

Per design discussion with @keyboardDrummer and @joehendrix: emit a Hole (unconstrained value) when a Composite-typed expression is returned from a function with Any return type. This avoids the type unification
crash while being honest about the limitation — the verifier treats the return value as unconstrained, which limits bug-finding but doesn't produce unsound results.

Auto-generated Composite -> Any coercions can be revisited once the broader Composite/Any typing design is resolved.

Changes:

  • Add coerceToAny helper that replaces Composite-typed expressions with a Hole when assigned to an Any-typed context
  • Apply coercion in return statement translation before assigning to LaurelResult
  • Add regression tests in VerifyPythonTest.lean and CBMC pipeline

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

When a Python function returns a typed service client, the return value
has type Composite but LaurelResult has type Any. Without coercion, Core
type checking fails with "Impossible to unify Any with Composite".

Add coerceToAny helper that wraps Composite values with
from_ClassInstance (serializing fields to DictStrAny) when assigning
to LaurelResult in return statements. Reuses the same pattern already
used for f-string interpolation of Composite values.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
@tautschnig tautschnig self-assigned this Apr 1, 2026
@tautschnig tautschnig requested review from a team and Copilot April 1, 2026 09:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a Core type-checking failure in the Python→Laurel pipeline when a Python function returns a composite-typed value while the generated LaurelResult output is typed as Any. It introduces a coercion step that wraps composite return values into the Any runtime representation (from_ClassInstance + DictStrAny of fields), and adds a regression test.

Changes:

  • Add coerceToAny helper to wrap composite expressions into Any via from_ClassInstance + serialized fields.
  • Apply coerceToAny to Python return statements before assigning to LaurelResult.
  • Add a CBMC pipeline test covering a function annotated -> Any that returns a class instance.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
Strata/Languages/Python/PythonToLaurel.lean Adds coerceToAny and uses it in return-statement translation to prevent Any vs Composite unification failures.
StrataTest/Languages/Python/tests/test_composite_return.py New regression test returning a composite value from a function typed as Any.
StrataTest/Languages/Python/tests/cbmc_expected.txt Registers the new test as expected PASS in the CBMC pipeline test list.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Strata/Languages/Python/PythonToLaurel.lean Outdated
Comment thread Strata/Languages/Python/PythonToLaurel.lean
Comment thread StrataTest/Languages/Python/tests/cbmc_expected.txt Outdated
- Add TODO comments on coerceToAny noting shared limitations with
  f-string interpolation: duplicated evaluation of translated expr
  in FieldSelect nodes, and no recursive handling of nested composites.
- Fix column alignment in cbmc_expected.txt.
- Add regression test in VerifyPythonTest exercising Composite return
  value coercion through the full Python → Laurel → Core → SMT pipeline.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
@tautschnig tautschnig enabled auto-merge April 1, 2026 11:27
@tautschnig tautschnig removed their assignment Apr 1, 2026
shigoel
shigoel previously approved these changes Apr 1, 2026
Copy link
Copy Markdown
Contributor

@shigoel shigoel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Comment thread Strata/Languages/Python/PythonToLaurel.lean
@tautschnig tautschnig self-assigned this Apr 2, 2026
tautschnig and others added 2 commits April 3, 2026 20:04
Per consensus from keyboardDrummer and joehendrix: emit a Hole
(unconstrained value) instead of building from_ClassInstance coercion
when a Composite-typed expression is assigned to an Any-typed variable
(e.g., LaurelResult in return statements).

This avoids the type unification crash while being honest about the
limitation — the verifier treats the return value as unconstrained,
which limits bug-finding but doesn't produce unsound results.

The from_ClassInstance coercion approach had additional issues (duplicated
evaluation, no nested composite support) that this sidesteps entirely.
Auto-generated coercions can be revisited once the Composite/Any typing
design is resolved.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
…posite

# Conflicts:
#	Strata/Languages/Python/PythonToLaurel.lean
@tautschnig tautschnig changed the title Coerce Composite return values to Any in Python return statements Emit Hole for Composite return values assigned to Any Apr 3, 2026
Comment thread StrataTest/Languages/Python/tests/test_composite_return.py
Comment thread StrataTest/Languages/Python/VerifyPythonTest.lean Outdated
Comment thread StrataTest/Languages/Python/tests/cbmc_expected.txt Outdated
tautschnig and others added 2 commits April 3, 2026 22:43
- Add missing 'from typing import Any' to test_composite_return.py
- Check diags.size == 0 in VerifyPythonTest instead of discarding
- Fix column alignment in cbmc_expected.txt

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
@tautschnig tautschnig added this pull request to the merge queue Apr 4, 2026
Merged via the queue into main with commit 9bba297 Apr 4, 2026
15 checks passed
@tautschnig tautschnig deleted the tautschnig/coerce-composite branch April 4, 2026 10:43
tautschnig added a commit that referenced this pull request Apr 6, 2026
The Hole-based Composite→Any coercion (from PR #727) causes CBMC
verification to fail. Skip for now.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants