EugeneK 22 Posted March 13 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
EugeneK 22 Posted March 13 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
DelphiUdIT 218 Posted March 13 TRecordLoader<T> = class sealed class function Get: T; static; If you use full generic declaration it works. Share this post Link to post
EugeneK 22 Posted March 13 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
Eric Grange 12 Posted March 18 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 1 Share this post Link to post
EugeneK 22 Posted March 24 Can anyone explain rationale why the suddenly change this and closed my ticket about this as by design? https://embt.atlassian.net/servicedesk/customer/portal/1/RSS-3043 This pisses me off they they randomly change compiler behaviour and not even in major version. And don't provide any explanation. Share this post Link to post
FredS 138 Posted March 24 1 hour ago, EugeneK said: why the suddenly change What I found when originally searching: https://stackoverflow.com/a/64526312 Share this post Link to post
Remy Lebeau 1542 Posted March 24 (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 March 24 by Remy Lebeau 1 Share this post Link to post
EugeneK 22 Posted March 25 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
Lars Fosdal 1835 Posted March 25 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
Eric Grange 12 Posted March 25 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
Remy Lebeau 1542 Posted March 25 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
FredS 138 Posted March 25 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
Lars Fosdal 1835 Posted Wednesday at 06:54 AM 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
Remy Lebeau 1542 Posted Wednesday at 07:22 AM 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
Lars Fosdal 1835 Posted Wednesday at 08:03 AM 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