View Issue Details

IDProjectCategoryView StatusLast Update
0023275FPCCompilerpublic2019-07-18 20:50
ReporterJC ChuAssigned ToSven Barth 
PrioritynormalSeveritymajorReproducibilityalways
Status assignedResolutionopen 
Platformx86_64OSWindows NTOS Version6.2.9200
Product Version2.7.1Product Build 
Target VersionFixed in Version 
Summary0023275: In Delphi mode, a type compatibly issue within generic code
DescriptionSee attached file for a demo.
Tagsgenerics, partial specialization
Fixed in Revision
FPCOldBugId
FPCTarget
Attached Files
  • D23275.pp (540 bytes)
    {$MODE DELPHI}
    
    type
      TPolicy<T> = class end;
    
      TWrapper<T, S> = class
        constructor Create(policy: TPolicy<T>);
      end;
    
      TSpecialWrapper<S> = class(TWrapper<Integer, S>)
      strict private
        type TSpecialPolicy = class(TPolicy<Integer>) end;
      public
        constructor Create;
      end;
    
    constructor TWrapper<T, S>.Create;
    begin
    end;
    
    constructor TSpecialWrapper<S>.Create;
    begin
      inherited Create(TSpecialPolicy);
        { Got "Class Of TSpecialWrapper$1.TSpecialPolicy", expected "TPolicy$1" }
    end;
    
    begin
    end.
    
    D23275.pp (540 bytes)

Activities

2012-11-05 13:44

 

D23275.pp (540 bytes)
{$MODE DELPHI}

type
  TPolicy<T> = class end;

  TWrapper<T, S> = class
    constructor Create(policy: TPolicy<T>);
  end;

  TSpecialWrapper<S> = class(TWrapper<Integer, S>)
  strict private
    type TSpecialPolicy = class(TPolicy<Integer>) end;
  public
    constructor Create;
  end;

constructor TWrapper<T, S>.Create;
begin
end;

constructor TSpecialWrapper<S>.Create;
begin
  inherited Create(TSpecialPolicy);
    { Got "Class Of TSpecialWrapper$1.TSpecialPolicy", expected "TPolicy$1" }
end;

begin
end.
D23275.pp (540 bytes)

Necem

2014-04-14 15:27

reporter   ~0074388

The Problem here is that your argument TSpecialPolicy is a class not an instance.

So either:
constructor TSpecialWrapper<S>.Create;
begin
  inherited Create(TSpecialPolicy.create);
end;

Or:
TWrapper<T, S> = class
type
  TPolicyClass = class of TPolicy<T>;
  
  constructor Create(policy: TPolicyClass);
end;

Sven Barth

2014-06-06 17:45

manager   ~0075532

Necem is right. Your code is not valid. Please recheck your code and report back if there is still a bug.

Note: the second solution provided by Necem does currently not compile. I'll need to fix this.

Regards,
Sven

JC Chu

2014-06-13 14:47

reporter   ~0075658

Wow… I can’t remember anything about it now but I guess I meant the first case. Curiously this “version 2.6.2 [2013/02/12] for i386” compiler does accept the erroneous source.

Sven Barth

2014-06-13 20:34

manager   ~0075666

Last edited: 2014-06-13 20:34

View 2 revisions

This might be, because the compiler doesn't do full checking when parsing a generic. It should however definitely error out when you specialize the generic.

If you did indeed mean the first case then the code should already correctly compile with 2.7.1.

Regards,
Sven

rd0x

2019-07-17 17:41

reporter   ~0117284

Possible close as solved?

Issue History

Date Modified Username Field Change
2012-11-05 13:44 JC Chu New Issue
2012-11-05 13:44 JC Chu File Added: D23275.pp
2012-11-05 13:44 JC Chu Tag Attached: generics
2014-04-11 18:18 Sven Barth Tag Attached: partial specialization
2014-04-14 15:27 Necem Note Added: 0074388
2014-06-06 17:45 Sven Barth Note Added: 0075532
2014-06-06 17:45 Sven Barth Assigned To => Sven Barth
2014-06-06 17:45 Sven Barth Status new => feedback
2014-06-13 14:47 JC Chu Note Added: 0075658
2014-06-13 14:47 JC Chu Status feedback => assigned
2014-06-13 20:34 Sven Barth Note Added: 0075666
2014-06-13 20:34 Sven Barth Note Edited: 0075666 View Revisions
2019-07-17 17:41 rd0x Note Added: 0117284