View Issue Details

IDProjectCategoryView StatusLast Update
0024073FPCCompilerpublic2017-04-05 15:15
ReporterMaciej Izak Assigned ToMaciej Izak  
PriorityhighSeveritymajorReproducibilityalways
Status resolvedResolutionfixed 
Product Version2.7.1 
Summary0024073: Wrong behavior of generic "record parameter"
DescriptionCheck out attached code:

program project4;

{$mode delphi}

type
  TA<T: record> = record
  end;

  TUnamanagedRec = record
    x: integer;
  end;

  TManagedRec = record
    s: string;
  end;

var
  a: TA<TUnamanagedRec>; // should pass and it is ok
  b: TA<TManagedRec>; // should pass and it is ok
  d: TA<Single>; // should pass but it's not ok in FPC! Error: Record type expected
  e: TA<Integer>; // should pass but it's not ok in FPC! Error: Record type expected
  f: TA<Pointer>; // shouldn't pass and it's half ok. Expected message is - E2512 Type parameter 'T' must be a non-nullable value type!
  g: TA<TObject>; // shouldn't pass and it's half ok. Expected message is - E2512 Type parameter 'T' must be a non-nullable value type!
  h: TA<string>; // shouldn't pass and it's half ok. Expected message is - E2512 Type parameter 'T' must be a non-nullable value type!
  // and so on...
begin
end.
Tagsgenerics
Fixed in Revision35739
FPCOldBugId
FPCTarget
Attached Files

Relationships

related to 0027206 resolvedSven Barth [Patch] Christmas gift by FreeSparta : Generics.Collections 

Activities

Maciej Izak

2013-03-18 12:05

reporter  

project4.lpr (912 bytes)

Sven Barth

2013-03-18 13:19

manager   ~0066359

Regarding the last three: We don't copy Delphi error message by error message.

And I also don't see why we should allow types like "Integer" or "Single" for "record" constraints...

Regards,
Sven

Maciej Izak

2013-03-18 14:08

reporter   ~0066362

Hi Sven :)

From Delphi doc (http://docwiki.embarcadero.com/RADStudio/XE3/en/Constraints_in_Generics#Record_Constraint):

'A type parameter may be constrained by zero or one instance of the reserved word "record". This means that the actual type must be a value type (not a reference type). A "record" constraint cannot be combined with a "class" or "constructor" constraint.'

I think that record word is ugly in that case, but have sense... Sometimes I use this. Maybe some other key word for that purpose? Sven pleas! For formalization! :).

Sven Barth

2013-03-19 09:10

manager   ~0066392

And again I have the urge to decimate the number of Delphi developers at Embarcadero -.-

Regards,
Sven

Maciej Izak

2013-06-17 01:24

reporter   ~0068338

First please decimate the number of C# developers at Microsoft ;). Similar concept.

http://msdn.microsoft.com/en-us/library/d5x73970.aspx

Regards,
HNB

Maciej Izak

2016-10-07 13:53

reporter  

0001-correct-handling-record-constraint-record-contraint-.patch (1,404 bytes)   
From aef58cb4c74c5d3e80d64e8d65751f5d38807d15 Mon Sep 17 00:00:00 2001
From: maciej-izak <hnb.code@gmail.com>
Date: Fri, 7 Oct 2016 13:52:46 +0200
Subject: [PATCH] correct handling "record" constraint (record contraint means
 non nilable type). Patch for: http://bugs.freepascal.org/view.php?id=24073

---
 compiler/pgenutil.pas | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/compiler/pgenutil.pas b/compiler/pgenutil.pas
index 7c63e4e..851daee 100644
--- a/compiler/pgenutil.pas
+++ b/compiler/pgenutil.pas
@@ -144,7 +144,17 @@ uses
               begin
                 case formaldef.typ of
                   recorddef:
-                    MessagePos(filepos,type_e_record_type_expected);
+                    case paradef.typ of
+                      floatdef,enumdef,orddef,stringdef,setdef,variantdef:
+                        continue;
+                      objectdef:
+                        if tobjectdef(paradef).objecttype = odt_object then
+                          continue
+                        else
+                          MessagePos(filepos,type_e_record_type_expected);
+                    else
+                      MessagePos(filepos,type_e_record_type_expected);
+                    end;
                   objectdef:
                     case tobjectdef(formaldef).objecttype of
                       odt_class,
-- 
2.9.3.windows.2

Maciej Izak

2016-10-07 13:53

reporter   ~0095008

Patch attached

Sven Barth

2016-10-13 19:35

manager   ~0095143

Your patch doesn't correspond with the example you wrote as your description as in the latter strings wouldn't pass, but according to your patch they would. So what is it?
And what about arrays (both dynamic and static) and file types?

Maciej Izak

2016-10-13 22:03

reporter  

0001-allow-static-array-types-and-file-types-for-record-g.patch (1,231 bytes)   
From 9a5a19eda4e102f84eb64fbfe14510d30bacea38 Mon Sep 17 00:00:00 2001
From: maciej-izak <hnb.code@gmail.com>
Date: Thu, 13 Oct 2016 21:52:07 +0200
Subject: [PATCH] allow static array types and file types for record generic
 constraint

---
 compiler/pgenutil.pas | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/compiler/pgenutil.pas b/compiler/pgenutil.pas
index 851daee..9adab29 100644
--- a/compiler/pgenutil.pas
+++ b/compiler/pgenutil.pas
@@ -145,8 +145,13 @@ uses
                 case formaldef.typ of
                   recorddef:
                     case paradef.typ of
-                      floatdef,enumdef,orddef,stringdef,setdef,variantdef:
+                      floatdef,enumdef,orddef,stringdef,setdef,variantdef,filedef:
                         continue;
+                      arraydef:
+                        if ado_IsDynamicArray in tarraydef(paradef).arrayoptions then
+                          MessagePos(filepos,type_e_record_type_expected)
+                        else
+                          continue;
                       objectdef:
                         if tobjectdef(paradef).objecttype = odt_object then
                           continue
-- 
2.9.3.windows.2

Maciej Izak

2016-10-13 22:03

reporter  

allow.pp (455 bytes)

Maciej Izak

2016-10-13 22:04

reporter  

fail1.pp (108 bytes)

Maciej Izak

2016-10-13 22:04

reporter  

fail2.pp (145 bytes)

Maciej Izak

2016-10-13 22:04

reporter  

fail3.pp (108 bytes)

Maciej Izak

2016-10-13 22:09

reporter   ~0095150

Last edited: 2016-10-13 22:10

View 2 revisions

yes, example is outdated, issue was created long before my fork work for nilable/nullable types. record constraint is dedicated to allow all not nilable/nullable types as generic parameter and is strictly related to "nilable"/"nullable" structures/types. Otherwise record constraint has no sense.

Improved patch for previous patch attached + examples.

Maciej Izak

2016-10-13 22:18

reporter   ~0095152

note: record constraint comes from Delphi for .NET and string type is not allowed in "Native Delphi" because string in .NET has 3 values: Null, Empty and Value. Mindless copying :P. If they like to have real nilable/nullable types in Delphi 10.3 (codename Carnival) they must to allow strings for record constraint in the future.

Maciej Izak

2016-10-14 10:01

reporter   ~0095156

you can add also a9: TA<file>; to allow.pp ;)

Maciej Izak

2017-04-05 15:15

reporter   ~0099387

For "record constraint" in Delphi mode we will keep Delphi compatible version. in ObjFPC will stay "as-is"

Issue History

Date Modified Username Field Change
2013-03-18 12:05 Maciej Izak New Issue
2013-03-18 12:05 Maciej Izak File Added: project4.lpr
2013-03-18 13:19 Sven Barth Note Added: 0066359
2013-03-18 14:08 Maciej Izak Note Added: 0066362
2013-03-19 09:09 Sven Barth Tag Attached: generics
2013-03-19 09:10 Sven Barth Note Added: 0066392
2013-06-17 01:24 Maciej Izak Note Added: 0068338
2015-01-06 14:31 Sven Barth Relationship added related to 0027206
2016-10-07 13:53 Maciej Izak File Added: 0001-correct-handling-record-constraint-record-contraint-.patch
2016-10-07 13:53 Maciej Izak Note Added: 0095008
2016-10-13 19:35 Sven Barth Note Added: 0095143
2016-10-13 19:35 Sven Barth Assigned To => Sven Barth
2016-10-13 19:35 Sven Barth Status new => assigned
2016-10-13 19:35 Sven Barth Status assigned => feedback
2016-10-13 22:03 Maciej Izak File Added: 0001-allow-static-array-types-and-file-types-for-record-g.patch
2016-10-13 22:03 Maciej Izak File Added: allow.pp
2016-10-13 22:04 Maciej Izak File Added: fail1.pp
2016-10-13 22:04 Maciej Izak File Added: fail2.pp
2016-10-13 22:04 Maciej Izak File Added: fail3.pp
2016-10-13 22:09 Maciej Izak Note Added: 0095150
2016-10-13 22:09 Maciej Izak Status feedback => assigned
2016-10-13 22:10 Maciej Izak Note Edited: 0095150 View Revisions
2016-10-13 22:18 Maciej Izak Note Added: 0095152
2016-10-14 10:01 Maciej Izak Note Added: 0095156
2017-04-05 14:57 Maciej Izak Assigned To Sven Barth => Maciej Izak
2017-04-05 15:15 Maciej Izak Fixed in Revision => 35739
2017-04-05 15:15 Maciej Izak Note Added: 0099387
2017-04-05 15:15 Maciej Izak Status assigned => resolved
2017-04-05 15:15 Maciej Izak Resolution open => fixed