IntersectMBO / IntersectMBO/plutus

BuiltinCasing crashes on GHC.Prim.Addr# when a join point exposes Data in its type

Open
#7,716 0 comments 0 reactions 1 assignee Claimed by @Unisay View on GitHub
bug Internal Plinth Plugin status: triaged
Dominant language
Haskell
Stars
1.6k
Forks
508
Avg merge
3d 10h
Merged PRs (30d)
22

Description

The plugin crashes when compiling a function with `datatypes=BuiltinCasing` if the GHC Core contains a join point with `PlutusCore.Data.Data` in its type:

```
Context: Compiling type: PlutusCore.Data.Data
Context: Compiling data constructor type: PlutusCore.Data.B
Context: Compiling type: Data.ByteString.Internal.Type.ByteString
Context: Compiling data constructor type: Data.ByteString.Internal.Type.BS
Context: Compiling type: GHC.Prim.Addr#
Error: Unsupported feature: Type constructor: GHC.Prim.Addr#
```

## What happens

`BuiltinData` wraps `PlutusCore.Data.Data`. Normally the plugin treats `BuiltinData` as a builtin and never looks inside. But GHC's simplifier can produce join points where `Data` appears naked in the type signature:

```
$j :: Data -> BuiltinUnit
```

The plugin with BuiltinCasing tries to compile `Data` as a regular ADT, follows `B ByteString` → `BS Addr# Int`, and crashes because `Addr#` has no Plutus Core equivalent.

## Reproduction

Branch with a failing test: [`yura/builtin-casing-addr-joinpoint`](https://github.com/IntersectMBO/plutus/tree/yura/builtin-casing-addr-joinpoint)

Minimal trigger — `caseList'` applied twice to the same value in a separate module without BuiltinCasing:

```haskell
failsToCompile :: BuiltinData -> BuiltinUnit
failsToCompile bd =
case toBuiltinData (firstOf items) of
_ -> case toBuiltinData (firstOf items) of
_ -> unitval
where
items = unsafeFromBuiltinData bd
firstOf = caseList' Nothing (\(h :: BuiltinData) _t -> Just h)
```

Compiled from `Spec.hs` (which has `datatypes=BuiltinCasing`) via `$$(compile [||Lib.failsToCompile||])`.

```bash
cabal build plutus-tx-plugin-tests
```

No dependencies beyond `plutus-tx` and `plutus-tx-plugin`.

## Originally discovered as

A cross-library compilation failure: a Plinth validator using `findOwnInput` + `getContinuingOutputs` from `plutus-ledger-api` crashed when compiled with BuiltinCasing. `getContinuingOutputs` calls `findOwnInput` internally, producing the double-call pattern that triggers the join point.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.