View Issue Details

IDProjectCategoryView StatusLast Update
0038497FPCCompilerpublic2021-02-22 10:47
ReporterOkobaPatino Assigned ToFlorian  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version3.3.1 
Fixed in Version3.3.1 
Summary0038497: Using Set types in generic will fail.
DescriptionThe "in" operator will fail with this message:
"Error: Set type expected"


program project1;

{$mode delphi}

type
  TEnum = (A, B, C);
  TSet = set of TEnum;

  procedure Test<TEnum, TSet>(E: TEnum; S: TSet);
  var
    I: TEnum;
  begin
    if E in S do
    WriteLn(E);
    for I := Low(TEnum) to High(TEnum) do
      if I in S then
        WriteLn(I);
  end;

begin
  Test<TEnum, TSet>(A, [A, B]);
end.
Tagsgenerics
Fixed in Revision48763
FPCOldBugId
FPCTarget-
Attached Files

Activities

Serge Anvarov

2021-02-16 16:38

reporter   ~0128955

And it is right.
I just rewrote your code with different names, for the compiler these two codes are equivalent:
[code]
{$mode delphi}

type
  TEnum = (A, B, C);
  TSet = set of TEnum;

  procedure Test<T1, T2>(E: T1; S: T2);
  var
    I: T1;
  begin
    if E in S do
      WriteLn(E);
    for I := Low(T1) to High(T1) do
      if I in S then
        WriteLn(I);
  end;

begin
  Test<TEnum, TSet>(A, [A, B]);
end.
[/code]

Akira1364

2021-02-16 16:56

reporter   ~0128956

Last edited: 2021-02-16 16:58

View 2 revisions

@SergeAnvarov

It still wouldn't compile even without the reported error the way you've written it... needs to look like this ("if E in S then", not "if E in S do"):

program Example;

{$mode Delphi}

type
  TEnum = (A, B, C);
  TSet = set of TEnum;

  procedure Test<T1, T2>(E: T1; S: T2);
  var
    I: T1;
  begin
    if E in S then
      WriteLn(E);
    for I := Low(T1) to High(T1) do
      if I in S then
        WriteLn(I);
  end;

begin
  Test<TEnum, TSet>(A, [A, B]);
end.

I'd say that this *does* reveal a compiler "inconsistency" overall. Considering that the fully generic "for I := Low(T1) to High(T1) do" for-loop works completely fine, there is no reason for the "in" statement to not also work IMO.

To me it just looks like whatever aspect of the compiler handles the parsing of "in" statements has not been fully adapted to account for delayed type instantiation in generic code, whereas the aspect of the compiler that handles the parsing of for-loops has.

Kai Burghardt

2021-02-16 19:26

reporter   ~0128957

Does the subset operator `[E] <= S` and `[I] <= S` work as expected?

OkobaPatino

2021-02-17 14:19

reporter   ~0128970

Here is an improved sample:

program project1;

{$mode delphi}

type
  TAlphabet = (A, B, C);
  TAlphabets = set of TAlphabet;

  procedure Test<TEnum, TSet>(E: TEnum; S: TSet);
  var
    I: TEnum;
    B: Boolean;
  begin
    B := [E] <= S;
    if E in S then
      WriteLn(E);
    for I := Low(TEnum) to High(TEnum) do
      if I in S then
      WriteLn(I);
  end;

begin
  Test<TAlphabet, TAlphabets>(A, [A, B]);
  ReadLn;
end.

@kays, yes it seem working.

OkobaPatino

2021-02-22 10:47

reporter   ~0129086

Tested. Thank you.

Issue History

Date Modified Username Field Change
2021-02-16 15:04 OkobaPatino New Issue
2021-02-16 16:38 Serge Anvarov Note Added: 0128955
2021-02-16 16:56 Akira1364 Note Added: 0128956
2021-02-16 16:58 Akira1364 Note Edited: 0128956 View Revisions
2021-02-16 19:26 Kai Burghardt Note Added: 0128957
2021-02-17 09:51 Sven Barth Tag Attached: generics
2021-02-17 14:19 OkobaPatino Note Added: 0128970
2021-02-21 22:30 Florian Assigned To => Florian
2021-02-21 22:30 Florian Status new => resolved
2021-02-21 22:30 Florian Resolution open => fixed
2021-02-21 22:30 Florian Fixed in Version => 3.3.1
2021-02-21 22:30 Florian Fixed in Revision => 48763
2021-02-21 22:30 Florian FPCTarget => -
2021-02-22 10:47 OkobaPatino Status resolved => closed
2021-02-22 10:47 OkobaPatino Note Added: 0129086