[Schrodinger's cat solution] Error: cannot supply body for package renaming

The error message named in the subject baffles me. I tried a MWE, to no avail: the error doesn’t reproduce. I tried pruning things down to a MWE, to no avail (so far): the error persists. :man_facepalming: If I figure it out, I’ll update, but if anyone has a hint, I’d be immensely grateful…

Without supplying hundreds of lines of code from 7 source files, the setup is: (not real names)

  • generic First_Value: Positive; package A, no body
  • generic Second_Value: Positive; package A.B, with body
  • generic package A.B.C, with body
  • generic package A.D, no body
  • package P, the main (test) program

(If it matters, they’re all in separate files.)

P uses all the names packages. The error is equivalent to

a-b-c.adb:8:01: error: cannot supply body for package renaming

But package A.B.C never appears in a renames clause, so what on earth is the error message referring to?!?

I suspect it has something to do with generics, but I can’t tell, nor can I make sense of the relevant compiler code:

      if Present (Corresponding_Spec (N)) then
         --  Body is body of package instantiation. Corresponding spec has
         --  already been set.
         Spec_Id := Corresponding_Spec (N);
         Pack_Decl := Unit_Declaration_Node (Spec_Id);
      else
         Spec_Id := Current_Entity_In_Scope (Defining_Entity (N));
         if Present (Spec_Id)
           and then Is_Package_Or_Generic_Package (Spec_Id)
         then
            Pack_Decl := Unit_Declaration_Node (Spec_Id);
            if Nkind (Pack_Decl) = N_Package_Renaming_Declaration then
               Error_Msg_N ("cannot supply body for package renaming", N);
               return;

Solved… in a Schrodinger’s :scream_cat: sort of manner.

TL;DR

:point_down:
alr clean
:point_up_2:

Wait, what?

No, really. That’s all it took.

Really?!? That’s all you did?

Unfortunately, no. That’s all I should have done. But it’s not all I did.

On my 3rd attempt to produce a MWE, I created a new alire crate, copied the source files over, then commented out a bunch of stuff. It compiled fine, so I un-commented more stuff. It still compiled, and at this point I was really sure I had passed this way when previously trimming to a MWE, so I decided to un-comment everything. It still compiled.
:astonished:
Next I put diff to work. Resolved some minor differences (whitespace, mostly…). It still compiled.
:face_with_spiral_eyes:
And no, the identical source files from the original repository still did not compile.
:crazy_face:
Hmm… you know what we :crab:s do in Rust when :ghost: spooky :ghost: stuff :ghost: like this happens? cargo clean. As I recall, alire has an equivalent… alr clean.
:tophat: :magic_wand: :rabbit2:
Just like that, the code compiled.

Moral of the story

No idea.

Why do I call it a Schrodinger’s :scream_cat: solution?

I imagine most readers know this and are screaming at the screen that this terminology is just a tad too cute, and completely wrong too boot.

But for the few of you who don’t, either because you’re baffled or just have to see if there’s a payoff (there’s not, you can quit now): in quantum mechanics, Schrodinger’s :scream_cat: is both dead and not-dead at the same time. Similarly, the code in this case was both erroneous and not erroroneous, as in: the Ada code was fine, but in the process of creating it, I somehow wrecked alire’s configuration to the point where it was completely confusing gnat, which produced an error that doubtless made sense to it, but made no sense at all to me.

Doubtless someone is annoyed that I have explained Schrodinger’s cat wrongly. Sorry; I both know the analogy and don’t know it.
:grin:

Immoral of the story, or, How did you wreck your code?

I refactored badly. Originally there were only two packages: A and P. But A had gotten long, much more involved than it needed to be, so I decided to refactor it. Hence A.B and A.B.C and A.D.

As you may have guessed, I’m not the world’s :trophy: best Ada coder, :medal_sports: so I made a hash of it several times along the way. I compiled a few times while things were not quite right, renamed packages more than once, accidentally had multiples copies of the same package in different files (some of these obviously wrong), all the while struggling with the correct use-age of generic child packages.

That’s it?

:flushed:
Yep.

Are there any redeeming features to this thread at all?!?

What, besides the emojis?
:grimacing:
Someday someone may encounter the same problem – um… hopefully someone besides me – and they’ll find this thread and get there a lot quicker?

Also, maybe, just maybe, you’ll encounter some absolutely bizarre gnat behavior which is not quite this one (or some absolutely bizarre rust rustc behavior… not that a hardened Ada dev would be using that… but… you know…) and you’ll think back to this and say to yourself, “hmm, alr clean helped someone in a similar position once, maybe I should try it,” so you try it, and it works.

Maybe.

2 Likes

What does MWE actually mean?

Minimum Working Example. In this case, one might argue I really wanted a Minimum Non-Working Example? Seems to me I’ve seen MWE used in both cases.

To elaborate, I wanted a setup with as few lines of code as possible, that preserved the structure of the packages I had, while replicating the compiler error.

Does that help?

I’ve seen it used that way a lot too. Either MWE or MCVE. I typically point folks to here for a much more expressive definition:

It has a good breakdown. Maybe we could tailor an Ada website page like this to help point new folks to it.

1 Like

On StackOverflow, you could comment with e.g. “please provide a [mcve].” The tag would get translated to appropriate text and, AFAICR, a link to that page.

SO liked to have text in the question, but here we’re rather more ephemeral*, so pastebin might do.

[*] OK, I might be thinking of gitter :frowning: