193 lines
7.0 KiB
Diff
193 lines
7.0 KiB
Diff
From 3f6a90f1ac47c480522a009d6ea56e2acfb7112f Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Nicol=C3=A1s=20Ojeda=20B=C3=A4r?= <n.oje.bar@gmail.com>
|
|
Date: Wed, 27 Apr 2022 14:46:47 +0200
|
|
Subject: [PATCH 1/9] Do not trigger warning when calling virtual methods
|
|
introduced by constraining "self" (#11204)
|
|
|
|
(cherry picked from commit 1e7af3f6261502bb384dc9e23a74ad0990bfd854)
|
|
---
|
|
Changes | 11 ++++++-
|
|
testsuite/tests/typing-objects/Tests.ml | 15 ++++++++++
|
|
typing/typeclass.ml | 40 ++++++++++---------------
|
|
3 files changed, 40 insertions(+), 26 deletions(-)
|
|
|
|
diff --git a/Changes b/Changes
|
|
index a8ce94bdc6..931a74b8d1 100644
|
|
--- a/Changes
|
|
+++ b/Changes
|
|
@@ -1,3 +1,13 @@
|
|
+OCaml 4.14 maintenance branch
|
|
+-----------------------------
|
|
+
|
|
+### Bug fixes:
|
|
+
|
|
+- #11204: Fix regression introduced in 4.14.0 that would trigger Warning 17 when
|
|
+ calling virtual methods introduced by constraining the self type from within
|
|
+ the class definition.
|
|
+ (Nicolás Ojeda Bär, review by Leo White)
|
|
+
|
|
OCaml 4.14.0 (28 March 2022)
|
|
----------------------------
|
|
|
|
@@ -62,7 +72,6 @@ OCaml 4.14.0 (28 March 2022)
|
|
definition-aware operations.
|
|
(Ulysse Gérard, Thomas Refis and Leo White, review by Florian Angeletti)
|
|
|
|
-
|
|
### Language features:
|
|
|
|
- #10462: Add attribute to produce a compiler error for polls.
|
|
diff --git a/testsuite/tests/typing-objects/Tests.ml b/testsuite/tests/typing-objects/Tests.ml
|
|
index f617bcf1b9..3dcd87c43c 100644
|
|
--- a/testsuite/tests/typing-objects/Tests.ml
|
|
+++ b/testsuite/tests/typing-objects/Tests.ml
|
|
@@ -955,6 +955,21 @@ Warning 17 [undeclared-virtual-method]: the virtual method m is not declared.
|
|
class c : object method m : int method n : int end
|
|
|}];;
|
|
|
|
+class virtual c = object (self : 'c)
|
|
+ constraint 'c = < f : int; .. >
|
|
+end
|
|
+[%%expect {|
|
|
+class virtual c : object method virtual f : int end
|
|
+|}];;
|
|
+
|
|
+class virtual c = object (self : 'c)
|
|
+ constraint 'c = < f : int; .. >
|
|
+ method g = self # f
|
|
+end
|
|
+[%%expect {|
|
|
+class virtual c : object method virtual f : int method g : int end
|
|
+|}];;
|
|
+
|
|
class [ 'a ] c = object (_ : 'a) end;;
|
|
let o = object
|
|
method m = 1
|
|
diff --git a/typing/typeclass.ml b/typing/typeclass.ml
|
|
index 048ee998b0..fedbc0e025 100644
|
|
--- a/typing/typeclass.ml
|
|
+++ b/typing/typeclass.ml
|
|
@@ -552,12 +552,11 @@ type first_pass_accummulater =
|
|
concrete_vals : VarSet.t;
|
|
local_meths : MethSet.t;
|
|
local_vals : VarSet.t;
|
|
- vars : Ident.t Vars.t;
|
|
- meths : Ident.t Meths.t; }
|
|
+ vars : Ident.t Vars.t; }
|
|
|
|
let rec class_field_first_pass self_loc cl_num sign self_scope acc cf =
|
|
let { rev_fields; val_env; par_env; concrete_meths; concrete_vals;
|
|
- local_meths; local_vals; vars; meths } = acc
|
|
+ local_meths; local_vals; vars } = acc
|
|
in
|
|
let loc = cf.pcf_loc in
|
|
let attributes = cf.pcf_attributes in
|
|
@@ -612,13 +611,6 @@ let rec class_field_first_pass self_loc cl_num sign self_scope acc cf =
|
|
(val_env, par_env, inherited_vars, vars))
|
|
parent_sign.csig_vars (val_env, par_env, [], vars)
|
|
in
|
|
- let meths =
|
|
- Meths.fold
|
|
- (fun label _ meths ->
|
|
- if Meths.mem label meths then meths
|
|
- else Meths.add label (Ident.create_local label) meths)
|
|
- parent_sign.csig_meths meths
|
|
- in
|
|
(* Methods available through super *)
|
|
let super_meths =
|
|
MethSet.fold
|
|
@@ -641,7 +633,7 @@ let rec class_field_first_pass self_loc cl_num sign self_scope acc cf =
|
|
in
|
|
let rev_fields = field :: rev_fields in
|
|
{ acc with rev_fields; val_env; par_env;
|
|
- concrete_meths; concrete_vals; vars; meths })
|
|
+ concrete_meths; concrete_vals; vars })
|
|
| Pcf_val (label, mut, Cfk_virtual styp) ->
|
|
with_attrs
|
|
(fun () ->
|
|
@@ -723,15 +715,11 @@ let rec class_field_first_pass self_loc cl_num sign self_scope acc cf =
|
|
let cty = transl_simple_type val_env false sty in
|
|
let ty = cty.ctyp_type in
|
|
add_method loc val_env label.txt priv Virtual ty sign;
|
|
- let meths =
|
|
- if Meths.mem label.txt meths then meths
|
|
- else Meths.add label.txt (Ident.create_local label.txt) meths
|
|
- in
|
|
let field =
|
|
Virtual_method { label; priv; cty; loc; attributes }
|
|
in
|
|
let rev_fields = field :: rev_fields in
|
|
- { acc with rev_fields; meths })
|
|
+ { acc with rev_fields })
|
|
|
|
| Pcf_method (label, priv, Cfk_concrete (override, expr)) ->
|
|
with_attrs
|
|
@@ -785,10 +773,6 @@ let rec class_field_first_pass self_loc cl_num sign self_scope acc cf =
|
|
raise(Error(loc, val_env,
|
|
Field_type_mismatch ("method", label.txt, err)))
|
|
end;
|
|
- let meths =
|
|
- if Meths.mem label.txt meths then meths
|
|
- else Meths.add label.txt (Ident.create_local label.txt) meths
|
|
- in
|
|
let sdefinition = make_method self_loc cl_num expr in
|
|
let warning_state = Warnings.backup () in
|
|
let field =
|
|
@@ -799,7 +783,7 @@ let rec class_field_first_pass self_loc cl_num sign self_scope acc cf =
|
|
let rev_fields = field :: rev_fields in
|
|
let concrete_meths = MethSet.add label.txt concrete_meths in
|
|
let local_meths = MethSet.add label.txt local_meths in
|
|
- { acc with rev_fields; concrete_meths; local_meths; meths })
|
|
+ { acc with rev_fields; concrete_meths; local_meths })
|
|
|
|
| Pcf_constraint (sty1, sty2) ->
|
|
with_attrs
|
|
@@ -837,11 +821,10 @@ and class_fields_first_pass self_loc cl_num sign self_scope
|
|
let local_meths = MethSet.empty in
|
|
let local_vals = VarSet.empty in
|
|
let vars = Vars.empty in
|
|
- let meths = Meths.empty in
|
|
let init_acc =
|
|
{ rev_fields; val_env; par_env;
|
|
concrete_meths; concrete_vals;
|
|
- local_meths; local_vals; vars; meths }
|
|
+ local_meths; local_vals; vars }
|
|
in
|
|
let acc =
|
|
Builtin_attributes.warning_scope []
|
|
@@ -850,7 +833,7 @@ and class_fields_first_pass self_loc cl_num sign self_scope
|
|
(class_field_first_pass self_loc cl_num sign self_scope)
|
|
init_acc cfs)
|
|
in
|
|
- List.rev acc.rev_fields, acc.vars, acc.meths
|
|
+ List.rev acc.rev_fields, acc.vars
|
|
|
|
and class_field_second_pass cl_num sign met_env field =
|
|
let mkcf desc loc attrs =
|
|
@@ -1003,7 +986,7 @@ and class_structure cl_num virt self_scope final val_env met_env loc
|
|
end;
|
|
|
|
(* Typing of class fields *)
|
|
- let (fields, vars, meths) =
|
|
+ let (fields, vars) =
|
|
class_fields_first_pass self_loc cl_num sign self_scope
|
|
val_env par_env str
|
|
in
|
|
@@ -1016,6 +999,13 @@ and class_structure cl_num virt self_scope final val_env met_env loc
|
|
update_class_signature loc val_env
|
|
~warn_implicit_public:false virt kind sign;
|
|
|
|
+ let meths =
|
|
+ Meths.fold
|
|
+ (fun label _ meths ->
|
|
+ Meths.add label (Ident.create_local label) meths)
|
|
+ sign.csig_meths Meths.empty
|
|
+ in
|
|
+
|
|
(* Close the signature if it is final *)
|
|
begin match final with
|
|
| Not_final -> ()
|
|
--
|
|
2.36.1
|
|
|