Skip to content

fix: use target type's instances in delta deriving#12339

Merged
kim-em merged 4 commits intomasterfrom
fix-deriving-diamond
Feb 16, 2026
Merged

fix: use target type's instances in delta deriving#12339
kim-em merged 4 commits intomasterfrom
fix-deriving-diamond

Conversation

@kim-em
Copy link
Copy Markdown
Collaborator

@kim-em kim-em commented Feb 6, 2026

This PR fixes a diamond problem in delta deriving where instance-implicit class parameters in the derived instance type were using instances synthesized for the underlying type, not the alias type.

When deriving an instance for a type alias (e.g., def ENat := WithTop ℕ), this caused a diamond when the alias has its own instance for a dependency class (e.g., AddMonoidWithOne from CommSemiring) that differs from the underlying type's instance (e.g., WithTop.addMonoidWithOne). Instance search would fail because it expected the alias's instance but the derived instance used the underlying's.

The fix: after synthesis succeeds, for each instance-implicit class parameter, re-synthesize for the target type and use that instance if it's defeq to what we synthesized for the underlying type.

Example

class MyBase (α : Type) where value : Nat := 42
class MyHigher (α : Type) [MyBase α] : Prop where prop : True

instance instBaseNat : MyBase Nat := {}
def MyAlias := Nat
instance instBaseMyAlias : MyBase MyAlias := {}  -- Different expression, but defeq

instance instHigherNat : MyHigher Nat where prop := trivial
deriving instance MyHigher for MyAlias

Before: instMyHigherMyAlias : @MyHigher MyAlias instBaseNat → instance search fails
After: instMyHigherMyAlias : @MyHigher MyAlias instBaseMyAlias → instance search succeeds

Motivation

This fixes the CharZero ℕ∞ diamond in Mathlib under #12179 where the derived instance was using WithTop.addMonoidWithOne instead of the AddMonoidWithOne from CommSemiring ℕ∞.

🤖 Prepared with Claude Code

@github-actions github-actions Bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Feb 6, 2026
mathlib-nightly-testing Bot pushed a commit to leanprover-community/batteries that referenced this pull request Feb 6, 2026
@github-actions github-actions Bot added the mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN label Feb 6, 2026
mathlib-nightly-testing Bot pushed a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Feb 6, 2026
leanprover-bot added a commit to leanprover/reference-manual that referenced this pull request Feb 6, 2026
@leanprover-bot leanprover-bot added the builds-manual CI has verified that the Lean Language Reference builds against this PR label Feb 6, 2026
@leanprover-bot
Copy link
Copy Markdown
Collaborator

leanprover-bot commented Feb 6, 2026

Reference manual CI status:

  • ✅ Reference manual branch lean-pr-testing-12339 has successfully built against this PR. (2026-02-06 06:47:38) View Log
  • 🟡 Reference manual branch lean-pr-testing-12339 build against this PR didn't complete normally. (2026-02-06 06:49:25) View Log
  • ❗ Reference manual CI can not be attempted yet, as the nightly-testing-2026-02-08 tag does not exist there yet. We will retry when you push more commits. If you rebase your branch onto nightly-with-manual, reference manual CI should run now. You can force reference manual CI using the force-manual-ci label. (2026-02-09 03:09:52)
  • ❗ Reference manual CI can not be attempted yet, as the nightly-testing-2026-02-15-rev1 tag does not exist there yet. We will retry when you push more commits. If you rebase your branch onto nightly-with-manual, reference manual CI should run now. You can force reference manual CI using the force-manual-ci label. (2026-02-15 21:12:43)

@mathlib-lean-pr-testing mathlib-lean-pr-testing Bot added the builds-mathlib CI has verified that Mathlib builds against this PR label Feb 6, 2026
@mathlib-lean-pr-testing
Copy link
Copy Markdown

mathlib-lean-pr-testing Bot commented Feb 6, 2026

Mathlib CI status (docs):

  • ✅ Mathlib branch lean-pr-testing-12339 has successfully built against this PR. (2026-02-06 07:37:57) View Log
  • ❗ Mathlib CI can not be attempted yet, as the nightly-testing-2026-02-15-rev1 tag does not exist there yet. We will retry when you push more commits. If you rebase your branch onto nightly-with-mathlib, Mathlib CI should run now. You can force Mathlib CI using the force-mathlib-ci label. (2026-02-15 21:12:41)

@kim-em kim-em force-pushed the fix-deriving-diamond branch from 9d4dcb6 to 5958320 Compare February 9, 2026 02:20
@kim-em kim-em added awaiting-mathlib We should not merge this until we have a successful Mathlib build changelog-language Language features and metaprograms labels Feb 9, 2026
mathlib-nightly-testing Bot pushed a commit to leanprover-community/batteries that referenced this pull request Feb 9, 2026
mathlib-nightly-testing Bot pushed a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Feb 9, 2026
@kim-em kim-em marked this pull request as ready for review February 9, 2026 03:36
@mathlib-lean-pr-testing mathlib-lean-pr-testing Bot removed the awaiting-mathlib We should not merge this until we have a successful Mathlib build label Feb 9, 2026
@mathlib-lean-pr-testing
Copy link
Copy Markdown

@kim-em kim-em requested review from kmill and nomeata and removed request for nomeata February 15, 2026 02:21
kim-em and others added 3 commits February 16, 2026 07:21
When deriving an instance for a type alias (e.g., `def ENat := WithTop ℕ`),
the instance-implicit class parameters in the derived instance TYPE were
using instances synthesized for the UNDERLYING type, not the ALIAS type.

This caused a diamond when the alias has its own instance for a dependency
class (e.g., AddMonoidWithOne from CommSemiring) that differs from the
underlying type's instance (e.g., WithTop.addMonoidWithOne). Instance
search would fail because it expected the alias's instance but the derived
instance used the underlying's.

The fix: after synthesis succeeds, for each instance-implicit class
parameter, re-synthesize for the target type and use that instance if
it's defeq to what we synthesized for the underlying type.

This fixes the `CharZero ℕ∞` diamond in Mathlib where the derived instance
was using `WithTop.addMonoidWithOne` instead of the `AddMonoidWithOne`
from `CommSemiring ℕ∞`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@kim-em kim-em force-pushed the fix-deriving-diamond branch from 5958320 to bf58299 Compare February 15, 2026 20:21
@github-actions github-actions Bot added the changes-stage0 Contains stage0 changes, merge manually using rebase label Feb 15, 2026
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

This is the final PR Bugbot will review for you during this billing cycle

Your free Bugbot reviews will reset on March 11

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Comment thread src/Lean/Elab/Tactic/BVDecide/LRAT/Trim.lean
Comment thread src/Lean/Elab/Tactic/BVDecide/LRAT/Trim.lean
Instead of silently using the underlying type's instance when a diamond
is detected, error if the instances for the target and underlying types
are not definitionally equal. This follows Joachim Breitner's suggestion
to behave as if the user wrote `instance : Cls T := inferInstanceAs (Cls T')`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot removed the changes-stage0 Contains stage0 changes, merge manually using rebase label Feb 15, 2026
@kim-em kim-em removed builds-mathlib CI has verified that Mathlib builds against this PR toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN labels Feb 15, 2026
@github-actions github-actions Bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Feb 15, 2026
mathlib-nightly-testing Bot pushed a commit to leanprover-community/batteries that referenced this pull request Feb 15, 2026
mathlib-nightly-testing Bot pushed a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Feb 15, 2026
@kim-em kim-em changed the base branch from nightly-with-mathlib to master February 16, 2026 00:30
@kim-em kim-em added the awaiting-mathlib We should not merge this until we have a successful Mathlib build label Feb 16, 2026
@kim-em kim-em enabled auto-merge February 16, 2026 00:31
@mathlib-lean-pr-testing mathlib-lean-pr-testing Bot added builds-mathlib CI has verified that Mathlib builds against this PR and removed awaiting-mathlib We should not merge this until we have a successful Mathlib build labels Feb 16, 2026
@mathlib-lean-pr-testing
Copy link
Copy Markdown

@kim-em kim-em added this pull request to the merge queue Feb 16, 2026
Merged via the queue into master with commit 5c7a508 Feb 16, 2026
44 of 45 checks passed
kim-em added a commit that referenced this pull request Feb 16, 2026
This PR fixes a diamond problem in delta deriving where
instance-implicit class parameters in the derived instance type were
using instances synthesized for the underlying type, not the alias type.

When deriving an instance for a type alias (e.g., `def ENat := WithTop
ℕ`), this caused a diamond when the alias has its own instance for a
dependency class (e.g., `AddMonoidWithOne` from `CommSemiring`) that
differs from the underlying type's instance (e.g.,
`WithTop.addMonoidWithOne`). Instance search would fail because it
expected the alias's instance but the derived instance used the
underlying's.

The fix: after synthesis succeeds, for each instance-implicit class
parameter, re-synthesize for the target type and use that instance if
it's defeq to what we synthesized for the underlying type.

### Example

```lean
class MyBase (α : Type) where value : Nat := 42
class MyHigher (α : Type) [MyBase α] : Prop where prop : True

instance instBaseNat : MyBase Nat := {}
def MyAlias := Nat
instance instBaseMyAlias : MyBase MyAlias := {}  -- Different expression, but defeq

instance instHigherNat : MyHigher Nat where prop := trivial
deriving instance MyHigher for MyAlias
```

**Before**: `instMyHigherMyAlias : @MyHigher MyAlias instBaseNat` →
instance search fails
**After**: `instMyHigherMyAlias : @MyHigher MyAlias instBaseMyAlias` →
instance search succeeds

### Motivation

This fixes the `CharZero ℕ∞` diamond in Mathlib under #12179 where the
derived instance was using `WithTop.addMonoidWithOne` instead of the
`AddMonoidWithOne` from `CommSemiring ℕ∞`.

🤖 Prepared with Claude Code

---------

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

Labels

builds-manual CI has verified that the Lean Language Reference builds against this PR builds-mathlib CI has verified that Mathlib builds against this PR changelog-language Language features and metaprograms mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants