To me the below behaviour appears inconsistent.
But before I file a bug, I want to double check, if maybe this is intention....

Tested with 3.2.3  and 3.3.1

Apparently
- when the generic TGen is compiled, it does check if a type "TRec1" and "TRec2" is in scope at all.
- it verifies that the generic itself compiles with that type
- **but** then it allows that type to be replaced by another, if the specialized param contains such another type

So if the specialized class, can have a type of it's own choosing for "TRec1" then why insist that a random other type of that name exists when the generic is declared. (And why reject "TRec2" as it too could be available at the time of specialization?)

Or should the specialized class "TClass1" use the global TRec1? and ignore TBase2.TRec1 ?


program testgen;
{$mode objfpc}{$H+}
type
  TRec1 = record r1: integer; end; // this will be used to check the generic itself

  TBase1 = class
  end;

  { TBase2 }

  TBase2 = class(TBase1)
  public type
    TRec1 = record r1_b2: integer; end; // this will be used in specialize
    TRec2 = record r2_b2: integer; end;
  end;

  generic TGen<B: TBase1> = class(B)
    f1: Trec1;  // here TBase2.Rec is not known
    //f2: Trec2;  //  Error: Identifier not found "Trec2"
    procedure x;
  end;

  TClass1 = class(specialize TGen<TBase2>)
    procedure Bar;
  end;

procedure TGen.x; // neither works...
begin
  //f1.r1 := 2;  // fails when specialized
  //f1.r1_b2 := 2;  // fails for the generic
end;

procedure TClass1.Bar;
begin
  f1.r1_b2 := 1; // This is TBase2.Rec, and compiles with 3.2.3  and 3.3.1
end;

begin
end.
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to