Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Compiler/Delphi/Generics    [ Add a report in this area ]  
Report #:  122833   Status: Closed
Compiler fails to recognize the default parameter value and shows the wrong error.
Project:  Delphi Build #:  XE4, XE5
Version:    19.2 Submitted By:   Zigmund Bulinsh
Report Type:  Basic functionality failure Date Reported:  2/28/2014 12:10:38 AM
Severity:    Serious / Highly visible problem Last Updated: 4/15/2014 6:31:30 PM
Platform:    All platforms Internal Tracking #:   48136
Resolution: Fixed (Resolution Comments) Resolved in Build: : XE6
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: 10
Description
When generic class has a method with a parameter of generic type with default value it fails to compile.
Steps to Reproduce:
Compile attached project.
Expected result: Success.
Actual result:
  [dcc32 Error] GenrericParamDefault.dpr(16): E2010 Incompatible types: 'System.Generics.Defaults.TComparer<GenrericParamDefault.TTest>' and 'System.Generics.Defaults.TComparer<uConfig.Types.TConfigExtractSubSet<T>.T>'

--------
program GenrericParamDefault;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  uConfig.Types;

type
  TTest = class
  end;

begin
  TConfigExtractSubSet<TTest>.ExtractSubSet(nil, nil, nil);
end.
--------

--------
unit uConfig.Types;

interface

uses
  System.Generics.Collections, System.Generics.Defaults;

type
  IConfigProvider = interface
    procedure Reload;
    function IsDirty: Boolean;
  end;

  IConfigObject<T> = interface
    function GetItems(ID: Integer): T;
    property Item[ID: Integer]: T read GetItems; default;
  end;

  TConfigExtractSubSetCallBack<T> = reference to function(AValue: T): Boolean;

  TConfigItemMap<T> = class(TDictionary<Integer, T>);

  TConfigExtractSubSet<T> = class sealed
    class function ExtractSubSet(AProvider: IConfigProvider; AItems: TConfigItemMap<T>;
      ACallBack: TConfigExtractSubSetCallBack<T>; ASortComparer: TComparer<T> = nil): TArray<T>;
  end;

implementation

{ TConfigExtractSubSet<T> }

class function TConfigExtractSubSet<T>.ExtractSubSet(AProvider: IConfigProvider; AItems: TConfigItemMap<T>;
  ACallBack: TConfigExtractSubSetCallBack<T>; ASortComparer: TComparer<T> = nil): TArray<T>;
var
  V: T;
  i: Integer;
begin
  if AProvider.IsDirty then
    AProvider.Reload;

  SetLength(Result, AItems.Count);
  i := 0;
  for V in AItems.Values do
    if ACallBack(V) then
      begin
        Result[i] := V;
        Inc(i);
      end;
  SetLength(Result, i);

  if Assigned(ASortComparer) then
    TArray.Sort<T>(Result, ASortComparer);
end;

end.
--------
Workarounds
None
Attachment
GenericParamDefault.zip
Comments

Zigmund Bulinsh at 2/28/2014 12:20:19 AM -
I tried to workaround it by declaring two same methods with "overload" directive. But then I got Internal Compiler Error URW1154 or something like that..

Server Response from: ETNACODE01