Skip to content

[ new,pragma ] add %ensure_identity#3785

Open
CodingCellist wants to merge 3 commits into
idris-lang:mainfrom
CodingCellist:ensure-id-pragma
Open

[ new,pragma ] add %ensure_identity#3785
CodingCellist wants to merge 3 commits into
idris-lang:mainfrom
CodingCellist:ensure-id-pragma

Conversation

@CodingCellist
Copy link
Copy Markdown
Member

@CodingCellist CodingCellist commented May 21, 2026

Description

This came up during in-person discussion with Ohad Kammar, during the 2026 May IDM: sometimes, it is useful to be able to annotate a function which should reduce to the identity function, but where one wants a warning if it did not.

Currently, the message prints 3 times for some reason, but otherwise appears to work!

TODO

Self-check

  • If this is a fix, user-facing change, a compiler change, or a new paper
    implementation, I have updated CHANGELOG_NEXT.md
  • I confirm that this contribution did not involve GenerativeAI nor Large Language Models.

This came up during in-person discussion with Ohad Kammar, during the
2026 May IDM: sometimes, it is useful to be able to annotate a function
which *should* reduce to the identity function, but where one wants a
warning if it did not.

Mostly this involves adding a `Warning` to `src/Core/Core.idr`, a
`DefFlag` to `src/Core/Context/Context.idr`, and a pragma and its
as-written-in-source version to `src/Idris/Syntax/Pragmas.idr` and
`src/Idris/Parser.idr` respectively.  The rest is then tracking that
annotation, updating TTImp and TTC to track it, and the myriad of
interfaces which this touches.

At the time of writing this commit, the message prints 3 times for some
reason, but otherwise appears to work!
@CodingCellist CodingCellist added enhancement event: IDM 2026/05 Issue tackled during the May 2026 Idris Developers Meeting labels May 21, 2026
@dunhamsteve
Copy link
Copy Markdown
Collaborator

Can we add this to source/reference/pragmas.rst, too?

@Z-snails
Copy link
Copy Markdown
Collaborator

The identity optimisation pass is run multiple times, since replacing a function with id can allow later functions to be detected as id. See

@stefan-hoeck
Copy link
Copy Markdown
Contributor

Very nice! Will this result in an error with --Werror?

@CodingCellist
Copy link
Copy Markdown
Member Author

Can we add this to source/reference/pragmas.rst, too?

Will do! Didn't know that was a thing, so thanks for pointing it out! : )


The identity optimisation pass is run multiple times, since replacing a function with id can allow later functions to be detected as id. See

Oh duh, it's the transform 3 call, presumably. Thank you! : D
I even remember noticing that call when I was working out where the identity optimisation actually happens. Clearly I just immediately forgot it again ^^;
But that would raise the warning three times, so it might just be expected behaviour?


Very nice! Will this result in an error with --Werror?

Just checked. Yes it will! : D

$ idris2 --check -Werror TestEnsureId.idr
1/1: Building TestEnsureId (TestEnsureId.idr)
Error: TestEnsureId.notId was explicitly annotated as reducing to the
identity function, but the compiler did not optimise it as such.

Error: TestEnsureId.notId was explicitly annotated as reducing to the
identity function, but the compiler did not optimise it as such.

Error: TestEnsureId.notId was explicitly annotated as reducing to the
identity function, but the compiler did not optimise it as such.

I had some confusion as to why the message was being printed 3 times.
It was pointed out by Z-snails that we call `transform 3`, since some
transformations may enable further optimisations.  This means we also
try to optimise the function to the identity 3 times, hence the repeated
warning message!

To make this clear to the user, I have updated the warning itself to
track which pass it was on, as well as updated the `setIdentity`
function to track which pass it is on (this is not entirely neat, as
transform-pass-numbering is done "in reverse" by recursion on a Nat).
The result is that the warning now includes the pass number, making it
clear that there are multiple transformation steps going on.  Hopefully
this is helpful, and if not, the commit can be reverted.
@CodingCellist
Copy link
Copy Markdown
Member Author

I added some code to track the number of transformation passes in the warning message itself. I think this is helpful, but if it clutters things too much, I'm happy to revert that commit : )

@dunhamsteve
Copy link
Copy Markdown
Collaborator

dunhamsteve commented May 22, 2026

The identity optimisation pass is run multiple times, since replacing a function with id can allow later functions to be detected as id.

So, with a warning on each pass, we might get two failures followed by a success? Is there a way to check and warn at the end.

E.g. we do this manually by doing :di foo and seeing if the runtime tree is x => x shaped, maybe we can do that after the compilation of runtime tree finishes?

@CodingCellist
Copy link
Copy Markdown
Member Author

Is there a way to check and warn at the end.

Possibly, but I'm not sure. I don't know whether the name gets transformed/mangled as part of the other optimisations, but if it doesn't we could track the name as part of the EnsureIdFailed warning, to spot if an optimisation succeeded.

Don't know how I would write a test to trigger that, however...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement event: IDM 2026/05 Issue tackled during the May 2026 Idris Developers Meeting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants