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

Type check Array[Foo] in module gets confused if Array[Foo] was already referenced in another precompiled module. #5350

Open
p6rt opened this issue May 29, 2016 · 7 comments

Comments

@p6rt
Copy link

p6rt commented May 29, 2016

Migrated from rt.perl.org#128287 (status was 'open')

Searchable as RT128287$

@p6rt
Copy link
Author

p6rt commented May 29, 2016

From autark@gmail.com

The bug can be reproduced with the following code spread over 3 files​:

main.pl6


use Zot;
zot();

Zot.pm6


use XXX;

sub zot() returns Array of Numeric is export {
  my Numeric @​a;
  return @​a;
}

XXX.pm6


my Numeric @​x;

When main.pl6 is run, the following error is reported​:
Type check failed for return value; expected Array[Numeric] but got
Array[Numeric].new()
  in sub zot at ./Zot.pm6 (Zot) line 5
  in block <unit> at main.pl6 line 2

$ perl6 --version
This is Rakudo version 2016.05-6-g2c45068 built on MoarVM version 2016.05
implementing Perl 6.c.

@p6rt
Copy link
Author

p6rt commented May 29, 2016

From @smls

Confirmed.

I tried to golf it down further, but this is the best I could do​:

  $ echo 'say Array[Int];' > B.pm
  $ echo 'use B; my Array[Int] $x = Array[Int].new;' > A.pm
  $ perl6 -I. -e 'use A;'

Which prints​:

  (Array[Int])
  (Array[Int])
  ===SORRY!===
  Type check failed in assignment to $x; expected Array[Int] but got Array[Int].new()

(Note​: Beside the type check failure, another curious thing is that the `say` is executed twice.)

The specific constellation needed to cause the issue, appears to be this​:

1) The mainline uses a module module, which performs a type check involving a parameterized type.
2) That module in turn uses another module, which instantiates that same parameterized type.

It's as if we end up with two "instances" of the same parameterized type, and the type check gets confused about which one to check against.

@p6rt
Copy link
Author

p6rt commented May 29, 2016

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented May 29, 2016

From @smls

UPDATE​:
It seems to be a precomp issue.
If precomp is disabled for B.pm, then the bug does not appear​:

  $ echo 'no precompilation; say Array[Int];' > B.pm

@p6rt
Copy link
Author

p6rt commented Dec 29, 2017

From github@zwell.net

On Sun, 29 May 2016 10​:28​:43 -0700, smls75@​gmail.com wrote​:

It's as if we end up with two "instances" of the same parameterized
type, and the type check gets confused about which one to check
against.

If I'm understanding the code correctly, it looks like that's what's happening. The error is coming from type_check_store() in container.c, and when I modified it to print the name and location of rcd->of and obj, the names were both Array[Int], but the memory locations were different.

You can confirm that by changing the test case (and get rid of the exception for now)​:
A.pm​:
use B;
say "A​: "~Array[Int].WHICH;
say "A (instance.WHAT)​: "~Array[Int].new.WHAT.WHICH;

B.pm​:
say "B​: "~Array[Int].WHICH;
say "B (instance.WHAT)​: "~Array[Int].new.WHAT.WHICH;

Then execute as before​:
perl6 -I. -e 'use A;'

If you ignore precomp, the output is​:
B​: Array[Int]|U132044096
B (instance.WHAT)​: Array[Int]|U132044096
A​: Array[Int]|U132044648
A (instance.WHAT)​: Array[Int]|U132044096

So in the context of A.pm, Array[Int].new is being associated with the correct type representation in memory, but (undefined) Array[Int] is not. (By the way, I checked .HOW as well and found that that is not having an extra instance created.)

So where are the type objects being created and failing to match with existing type objects? Is this type_object_for() in VMArray.c?

@p6rt
Copy link
Author

p6rt commented Dec 29, 2017

From github@zwell.net

Also, if you print the .WHICH values during BEGIN, you'll find that they're consistent, so the problem occurs either when compiling A.pm or reading the precompiled data.

@p6rt p6rt added the Bug label Jan 5, 2020
@usev6
Copy link

usev6 commented Oct 8, 2023

This seems to work nowadays:

$ mkdir gh5350
$ echo 'use XXX; sub zot() returns Array of Numeric is export { my Numeric @a; return @a }' >gh5350/Zot.rakumod
$ echo 'my Numeric @x' >gh5350/XXX.rakumod
$ ./rakudo-m -Igh5350 -e 'use Zot; zot(); say "alive"'
alive

And also:

$ mkdir -p gh5350
$ echo 'say Array[Int]' >gh5350/B.rakumod
$ echo 'use B; my Array[Int] $x = Array[Int].new' >gh5350/A.rakumod
$ ./rakudo-m -Igh5350 -e 'use A'
(Array[Int])
(Array[Int])
$ ./rakudo-m -Igh5350 -e 'use A'
(Array[Int])

Tagging "testneeded".

(Btw, from the error message this could be the same problem reported in #6650.)

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

No branches or pull requests

2 participants