chapel-lang / chapel

a Productive Parallel Programming Language
https://chapel-lang.org
Other
1.78k stars 418 forks source link

Scoped enum offset issues #7681

Open cassella opened 6 years ago

cassella commented 6 years ago

Summary of Problem

A few uses of a scoped enum with an offset fail to compile, when I think they should work.

Steps to Reproduce

Source Code:

[ edit 7/19/2024 cassella -- only the last of these examples still fails. ]

enumScopeTest(2);
enumScopeTest(3);
proc enumScopeTest(param x) {
  enum Numbers {one=x, two, three};
  writeln(Numbers.one);
}
scope-param-offset.chpl:5: error: enumerator 'one' is not an integer param value

Maybe it needs to be reassured that x is an int param?

enumScopeTest(2);
enumScopeTest(3);
proc enumScopeTest(param x:int) {
  enum Numbers {one=x, two, three};
  writeln(Numbers.one);
}
scope-param-offset-type-2.chpl:5: error: enumerator 'one' is not an integer param value

Try to impart this reassurance a different way?

enumScopeTest(2);
enumScopeTest(3);
proc enumScopeTest(param x) {
  enum Numbers {one=x:int, two, three};
  writeln(Numbers.one);
}
scope-param-offset-type.chpl:5: internal error: CAL0120 chpl Version 1.17.0 pre-release (cf54f6a)
...

It also doesn't work if the param x is global (and the function the enum is within is now concrete):

enumScopeTest();
param x = 2;
proc enumScopeTest() {
  enum Numbers {one=x, two, three};
  writeln(Numbers.one);
}
$CHPL_HOME/modules/standard/Types.chpl:607: internal error: TYP0356 chpl Version 1.17.0 pre-release (cf54f6a)

It works if the enum and writeln are at file scope with x.

Edit 3/15/2019: The error for this is now:

internal error: Unable to resolve enumerator type expression [resolution/functionResolution.cpp:6183]

Edit, part 2: I also noticed that if the call to enumScopeTest() is moved to after the function's definition, or even to just after the param x = 2 line, it compiles and runs.

FWIW, the spec doesn't spell out in 7.2 Enumerated Types that the init-part expression has to be a param.

Associated Future Test(s):

test/types/enum/scope-param-offset-type.chpl test/types/enum/scope-param-offset-type-2.chpl test/types/enum/scope-param-offset-concrete.chpl test/types/enum/scope-param-offset.chpl

[edit 11/1 cassella: add links to futures ]

Configuration Information

This is with chpl built from master late Friday,

fortytwo@magrathea:~/src/chapel/test/types/enum (generic-function-enums)$ chpl --version 
chpl Version 1.17.0 pre-release (cf54f6a)
Copyright (c) 2004-2017, Cray Inc.  (See LICENSE file for more details)
fortytwo@magrathea:~/src/chapel/test/types/enum (generic-function-enums)$ printchplenv --anonymize
CHPL_TARGET_PLATFORM: linux64
CHPL_TARGET_COMPILER: gnu
CHPL_TARGET_ARCH: native *
CHPL_LOCALE_MODEL: flat
CHPL_COMM: gasnet *
  CHPL_COMM_SUBSTRATE: udp
  CHPL_GASNET_SEGMENT: everything
CHPL_TASKS: qthreads
CHPL_LAUNCHER: amudprun
CHPL_TIMERS: generic
CHPL_UNWIND: none
CHPL_MEM: jemalloc
CHPL_MAKE: make
CHPL_ATOMICS: intrinsics
  CHPL_NETWORK_ATOMICS: none
CHPL_GMP: gmp
CHPL_HWLOC: hwloc
CHPL_REGEXP: re2
CHPL_AUX_FILESYS: none
fortytwo@magrathea:~/src/chapel/test/types/enum (generic-function-enums)$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609
ben-albrecht commented 6 years ago

Thanks for reporting @cassella!

This seems like a natural follow-up to #5414. @lydia-duncan might have more info.

For more information, I tried compiling the internal error cases with --devel to get the actual error messages:

enumScopeTest(2);
enumScopeTest(3);
proc enumScopeTest(param x) {
  enum Numbers {one=x:int, two, three};
  writeln(Numbers.one);
}
> chpl a.chpl --devel
a.chpl:3: In function 'enumScopeTest':
a.chpl:5: error: use of 'one' before encountering its definition, type unknown
enumScopeTest();
param x = 2;
proc enumScopeTest() {
  enum Numbers {one=x, two, three};
  writeln(Numbers.one);
}
> chpl b.chpl --devel
$CHPL_HOME/modules/standard/Types.chpl:607: internal error: assertion error [type.cpp:353]
Note: This source location is a guess.
lydia-duncan commented 6 years ago

Based on looking at the code last week, I suspect something is preventing param folding to occur when it resolves the init expression. I'm disappointed, but not surprised, since it goes through a specialized code path that was broken in a pretty stupid way before I fixed it slightly

I'm not sure whether we should limit enum constant values to compile time constants, but agree that if we do, we should document that limitation. I'll bring that up at our weekly status meeting with the rest of my enum notes.

lydia-duncan commented 6 years ago

Please open a PR to check these into the testing system :)

lydia-duncan commented 6 years ago

@mppf - was this case handled by your open branch?

mppf commented 6 years ago

@lydia-duncan - thanks for asking. My PR changes some of the ways in which enum constants are initialized but I don't think it fundamentally changes this bug. I think what's going on here is that the enum's constant isn't being substituted appropriately during function resolution. Perhaps the change you proposed (changing where enum functions are stored in the AST) might help. Alternatively, it might be as simple as passing along (and using) a SymbolMap in to ensureEnumTypeResolved.

bradcray commented 6 years ago

PR #10114 will retire test/types/enum/scope-param-offset-type-2.chpl

bradcray commented 6 years ago

This issue seems loosely related to #10115 in that it's the compiler working hard to compute the param values of the enums that's going off the rails. I could imagine retiring these futures either by making our computation of enums' param values more robust, or by having the compiler stop trying so hard to compute their values at compile-time.

cassella commented 2 months ago

@vasslitvinov I think github was overzealous in closing this issue due to the last paragraph in 4881bf6. test/types/enum/scope-param-offset-concrete.chpl is still a failing future.

I was reminded of this by #22307 .

github also isn't showing me a Reopen button.