generics chapter 8.8 "A word about scope" needs maybe a remark about accessing members of T that are not yet specialized.
Original Reporter info from Mantis: Thaddy
-
Reporter name: Thaddy de Koning
Original Reporter info from Mantis: Thaddy
- Reporter name: Thaddy de Koning
Description:
related to 0033700
Given the following code:
generic TLstEnumerator<T> = record
private
lst, lst_save: T;
public
constructor Create(const Value: T);
function GetEnumerator: specialize TLstEnumerator<T>;
function MoveNext: boolean;
property Current: T read lst;
end;
constructor TLstEnumerator.Create(const Value: T);
begin
lst := Value;
lst_save := nil;
end;
function TLstEnumerator.GetEnumerator: specialize TLstEnumerator<T>;
begin
Result := Self;
end;
function TLstEnumerator.MoveNext: boolean;
begin
if lst <> nil then
begin
// At this point it is simply not known that lst is a type that has
// a field called next. So the compiler throws an illegal qualifier.
// The compiler is correct. This is not a bug! lst is not in scope here.
lst:=lst^.next;
Result := True;
end else Result := False;
end;
Here the programmer knows that T has a specific member, but the compiler can not know that at that point. It has not enough context within that scope to resolve T fully.
Steps to reproduce:
Compile my files attached to 0033700
- mode delphi
- mode objfpc
Note Delphi barks even more but essentially also does not accept such code.
Additional information:
It is simply not clear to OP from 0033700 that lst^.next is not specialized at all at that point. That needs maybe some clarification in the documentation.
I filed it as a separate bug report because I feel it belongs to documentation.
Mantis conversion info:
- Mantis ID: 33960
- OS: all
- OS Build: all
- Build: 39423
- Platform: all
- Version: 3.1.1
- Fixed in version: 3.1.1
- Fixed in revision: 1493 (#fa246ac5)
- Target version: 3.2.0