Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parameter arguments of projections of instance-opened record type are not erased #5769

Closed
jespercockx opened this issue Feb 1, 2022 · 12 comments
Assignees
Labels
erasure instance Instance resolution not-in-changelog This issue should not be listed in the changelog. records Record declarations, literals, constructors and updates type: bug Issues and pull requests about actual bugs
Milestone

Comments

@jespercockx
Copy link
Member

Consider the following code:

postulate A : Set

record R (a : A) : Set where
  field f : A

open R {{...}}

g : {@0 x : A} {{_ : R x}}  A
g {x} {{r}} = f {x} {{r}}

This results in the following error:

Variable x is declared erased, so it cannot be used here
when checking that the expression x has type A

In contrast, defining g {x} {{r}} = R.f {x} r instead works just fine. So this looks like there's a bug in the implementation of the instance-open syntax {{...}}.

@jespercockx jespercockx added type: bug Issues and pull requests about actual bugs records Record declarations, literals, constructors and updates instance Instance resolution erasure labels Feb 1, 2022
@jespercockx jespercockx added this to the 2.6.3 milestone Feb 1, 2022
@jespercockx jespercockx self-assigned this Feb 1, 2022
@jespercockx
Copy link
Member Author

Workaround until this is fixed: instead of using the {{...}} syntax, define f by hand:

f : {@0 x : A} {{_ : R x}}  A
f {{r}} = R.f r

@nad
Copy link
Contributor

nad commented Feb 1, 2022

Note that the parameters are erased in the type of the record constructor, but not in the record module's telescope (#4786 (comment)).

@jespercockx
Copy link
Member Author

Yeah, now I actually wish it were possible to mark the module parameters of the record module as erased, but without marking the arguments to the record type as erased.

@jespercockx
Copy link
Member Author

Actually, would that be a reasonable thing to do? We are already changing the visibility of the record parameters to be hidden; why not also change the quantity to @0 at the same time?

@nad
Copy link
Contributor

nad commented Feb 1, 2022

A workaround, if you really want to have a module with the same name as the record type:

module _ where

module Record where

  record R (A : Set₂) : Set₂ where
    field
      x : A

open Record public hiding (module R)

module R {@0 A : Set₂} (r : R A) where

  x : A
  x = Record.R.x r

r₁ : R Set₁
r₁ = record { x = Set }

r₂ : R Set₁
r₂ .Record.R.x = Set

@nad
Copy link
Contributor

nad commented Feb 1, 2022

Actually, would that be a reasonable thing to do? We are already changing the visibility of the record parameters to be hidden; why not also change the quantity to @0 at the same time?

It is not necessarily the case that all code in a record module can be type-checked when the parameters are erased.

@jespercockx
Copy link
Member Author

jespercockx commented Feb 1, 2022

A workaround, if you really want to have a module with the same name as the record type:
[...]

Yes that works, unfortunately I also do care about being able to use the actual unqualified name of the field in copatterns.

It is not necessarily the case that all code in a record module can be type-checked when the parameters are erased.

That is something we could check. (At the cost of throwing error messages about erasure at users who did not use erasure in their code.)

@nad
Copy link
Contributor

nad commented Feb 1, 2022

That is something we could check.

Are you suggesting that we should see if the code type-checks with @0, and only change the telescope if it does? I would prefer if the user had to declare their intention more explicitly. One could imagine using some kind of keyword in the record type's header, but what if you want to mark only some parameters as erased in the record module? I suggest that we first get some experience with this kind of code, and then work out a design once we know what we want to do. I have at least one example in which one can't make all parameters erased.

@jespercockx
Copy link
Member Author

Yeah no I agree completely that we should not decide on whether or not it checks, what I meant was that we might just always mark parameters of the record module as erased. But this doesn't seem possible since you have an example that would be broken by this change. So perhaps a specific keyword to toggle on erasure of record parameters would be the best solution.

Independently of whether we decide to add such a keyword, I still consider the behaviour of the original example I posted here a bug that should be fixed regardless.

@jespercockx
Copy link
Member Author

I've made a separate issue for erasure of module parameters from definitions inside the record module: #5770

@anuyts
Copy link
Contributor

anuyts commented Aug 22, 2022

Side-note: see here for a remark on what "instance-opening" really is.

@jespercockx
Copy link
Member Author

I've added the --erase-record-parameters flag in #5770 and I'm happy with it, so I am not planning to do more about this issue.

@nad nad added the not-in-changelog This issue should not be listed in the changelog. label Nov 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
erasure instance Instance resolution not-in-changelog This issue should not be listed in the changelog. records Record declarations, literals, constructors and updates type: bug Issues and pull requests about actual bugs
Projects
None yet
Development

No branches or pull requests

3 participants