瀏覽代碼

* Fix usage of class operators in generics types. If we have generic type declaration/implementation then constraint in comparison to not specialized generic is not "exact" nor "incompatible". Mantis #30534.

git-svn-id: trunk@35740 -
maciej-izak 8 年之前
父節點
當前提交
ff28d5c85d
共有 3 個文件被更改,包括 61 次插入5 次删除
  1. 1 0
      .gitattributes
  2. 17 5
      compiler/defcmp.pas
  3. 43 0
      tests/webtbs/tw30534b.pp

+ 1 - 0
.gitattributes

@@ -15364,6 +15364,7 @@ tests/webtbs/tw30524a.pp svneol=native#text/pascal
 tests/webtbs/tw30524b.pp svneol=native#text/pascal
 tests/webtbs/tw30530.pp svneol=native#text/pascal
 tests/webtbs/tw30534.pp svneol=native#text/pascal
+tests/webtbs/tw30534b.pp svneol=native#text/pascal
 tests/webtbs/tw30535.pp svneol=native#text/pascal
 tests/webtbs/tw30537.pp svneol=native#text/pascal
 tests/webtbs/tw30552.pp svneol=native#text/pascal

+ 17 - 5
compiler/defcmp.pas

@@ -296,11 +296,23 @@ implementation
                      exit;
                    end;
 
-                 { one is definitely a constraint, for the other we don't
-                   care right now }
-                 doconv:=tc_equal;
-                 compare_defs_ext:=te_exact;
-                 exit;
+                 { maybe we are in generic type declaration/implementation.
+                   In this case constraint in comparison to not specialized generic
+                   is not "exact" nor "incompatible" }
+                 if not(((df_genconstraint in def_from.defoptions) and
+                        ([df_generic,df_specialization]*def_to.defoptions=[df_generic])
+                      ) or
+                      (
+                        (df_genconstraint in def_to.defoptions) and
+                        ([df_generic,df_specialization]*def_from.defoptions=[df_generic]))
+                    ) then
+                   begin
+                     { one is definitely a constraint, for the other we don't
+                       care right now }
+                     doconv:=tc_equal;
+                     compare_defs_ext:=te_exact;
+                     exit;
+                   end;
                end;
            end;
 

+ 43 - 0
tests/webtbs/tw30534b.pp

@@ -0,0 +1,43 @@
+{ %NORUN }
+
+{$mode delphi}
+
+type
+  TNullable<T: record> = record
+  public type
+    PT = ^T;
+  public
+    class operator Implicit(A: PT): TNullable<T>;
+    class operator Implicit(A: T): TNullable<T>;
+    class operator Equal(A: TNullable<T>; B: PT): Boolean;
+    class operator Equal(A: TNullable<T>; B: T): Boolean;
+  end;
+
+  TRec = record
+  end;
+
+class operator TNullable<T>.Implicit(A: PT): TNullable<T>;
+begin
+end;
+
+class operator TNullable<T>.Implicit(A: T): TNullable<T>;
+begin
+end;
+
+class operator TNullable<T>.Equal(A: TNullable<T>; B: PT): Boolean;
+begin
+end;
+
+class operator TNullable<T>.Equal(A: TNullable<T>; B: T): Boolean;
+begin
+end;
+
+var
+  x: TNullable<integer>;
+  y: TNullable<TRec>;
+begin
+  x := nil;
+  x := 1;
+  if x = nil then ;
+  if x = 1 then ;
+end.