Jump to content
EugeneK

[dcc32 Error] Type parameter 'T' must be a non-nullable value type

Recommended Posts

Hi

 

Anyone else have this error in 12.3

[dcc32 Error] Type parameter 'T' must be a non-nullable value type

Works fine in 12.2, trying to isolate it now, seems to work in some places but not the others.

Share this post


Link to post

Happens when record field has an attribute

unit UTestGenericsBug;

interface

uses
  System.Rtti,
  Data.DB;

type
  DBField = class(TCustomAttribute)
  strict private
    FFieldType: TFieldType;
    FLength: Integer;
  public
    constructor Create(const AFieldType: TFieldType = ftUnknown; const ALength: Integer = 0);
    property FieldType: TFieldType read FFieldType;
    property Length: Integer read FLength;
  end;

  TTestRecord = record
  private
    [DBField(ftString, 20)]
    FTerminalName: string;
  public
  end;

  TRecordLoader<T: record> = class sealed
    class function Get: T; static;
  end;

implementation

constructor DBField.Create(const AFieldType: TFieldType = ftUnknown; const ALength: Integer = 0);
begin

end;

class function TRecordLoader<T>.Get: T;
begin
  Result := Default(T);
end;

function Get: TTestRecord;
begin
  // error here
  Result := TRecordLoader<TTestRecord>.Get;
end;

end.

😒

Share this post


Link to post
TRecordLoader<T> = class sealed
    class function Get: T; static;

If you use full generic declaration it works.

Share this post


Link to post
Just now, DelphiUdIT said:

TRecordLoader<T> = class sealed
    class function Get: T; static;

If you use full generic declaration it works.

Yes I'll probably use it as a workaround, but that kind of defeats the purpose

Share this post


Link to post

This issue doesn't need an attribute to be triggered, but just any kind of dynamic field (a string, a dynamic array, etc.)

And yes, it makes the "record" constraint rather corner-case now

  • Thanks 1

Share this post


Link to post
Posted (edited)
1 hour ago, FredS said:

What I found when originally searching: https://stackoverflow.com/a/64526312

That StackOverflow post is about the error on a Custom Managed Record, but the code shown above is not using a CMR.  It is just a regular Managed Record due to the string field (has nothing to do with the custom Attribute).  And according to RSS-3043 (which has been closed last week as "As Designed"):

Quote

This is actually as designed, managed records (including records with strings) cannot be use for generics restricted to records (where record is in fact traditional memory managed records). It's a restriction from the past, done to avoid bugs

 

Edited by Remy Lebeau
  • Thanks 1

Share this post


Link to post
10 hours ago, Remy Lebeau said:

This is actually as designed, managed records (including records with strings) cannot be use for generics restricted to records (where record is in fact traditional memory managed records). It's a restriction from the past, done to avoid bugs

But this is simply not true because managed records can be used for generics restricted to records in 12.2 and before. I had a lot of code broken because of this change that worked perfectly fine.

Share this post


Link to post

Same for me.

Several record types where I had to explicitly add a string length, resulting in numerous [dcc32 Warning]: W1057 Implicit string cast from 'ShortString' to 'string'

Share this post


Link to post

Same here. It was working fine in 12.2 & before.
With the workaround it "works", but the generated code is less efficient, and the generic now "accepts" types it wasn't intended for.

Share this post


Link to post
6 hours ago, Lars Fosdal said:

Several record types where I had to explicitly add a string length, resulting in numerous [dcc32 Warning]: W1057 Implicit string cast from 'ShortString' to 'string'

That has nothing to do with Generics (the topic of this discussion).

 

Specifying an explicit length on a string at compile-time will produce an AnsiChar-based ShortString, and always has. That's nothing new. Assigning an Ansi string to a Unicode string (or vice versa) requires a data conversion at runtime, which can potentially lose data, hence the warning. 

Share this post


Link to post
12 hours ago, EugeneK said:

But this is simply not true because managed records can be used for generics restricted to records in 12.2 and before. I had a lot of code broken because of this change that worked perfectly fine.

Managed records took a long time to fully implement and yes, records with strings where not managed or let's call them pseudo-managed and allowed.

 

That only leaves the Q why fix or enforce this in: 12.2>12.3..

 

Share this post


Link to post
16 hours ago, Remy Lebeau said:

That has nothing to do with Generics (the topic of this discussion).

That is technically correct but simply changing from string to string[n] in a record as a workaround to the non-nullable type Generics issue, will cause these warnings.

Share this post


Link to post
18 minutes ago, Lars Fosdal said:

simply changing from string to string[n] in a record as a workaround to the non-nullable type Generics issue, will cause these warnings.

(Ansi|Unicode|Wide)String are managed types. String[n] (ShortString) is not. But switching to ShortString has its own share of compatibility issues not related to Generics.

Share this post


Link to post
25 minutes ago, Remy Lebeau said:

(Ansi|Unicode|Wide)String are managed types. String[n] (ShortString) is not. But switching to ShortString has its own share of compatibility issues not related to Generics.

Indeed. The change to 12.3 is really complicating existing code, and although I am not against breaking changes for improving quality, it means that you can't really use 12.3 without rewriting parts of the code.

 

Since we never did go for 12.0 ,12.1 or 12.2, I suspect our projects will stay on 11.3, since the product has entered the care and maintenance phase.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×