diff --git a/src/typing/matcher/texprConverter.ml b/src/typing/matcher/texprConverter.ml index 8c568a1f77a..0d2408c8701 100644 --- a/src/typing/matcher/texprConverter.ml +++ b/src/typing/matcher/texprConverter.ml @@ -77,9 +77,10 @@ let unify_constructor ctx params t con = | _ -> Some(con,params) -let rec extract_const e = match e.eexpr with - | TConst ct -> Some ct - | TCast(e1,None) -> extract_const e1 +let rec extract_ctor e = match e.eexpr with + | TConst ct when ct <> TNull -> Some (ConConst ct) + | TField(_,FEnum(en,ef)) -> Some (ConEnum(en,ef)) + | TCast(e1,None) -> extract_ctor e1 | _ -> None let all_ctors ctx e cases = @@ -117,32 +118,36 @@ let all_ctors ctx e cases = let add constructor = Compile.ConTable.replace h constructor true in - let rec loop t = match follow t with + let rec loop deep t = match follow t with | TAbstract({a_path = [],"Bool"},_) -> - add (ConConst(TBool true),null_pos); - add (ConConst(TBool false),null_pos); + if not deep then begin + add (ConConst(TBool true),null_pos); + add (ConConst(TBool false),null_pos); + end; SKValue,RunTimeFinite | TAbstract({a_impl = Some c} as a,pl) when a.a_enum -> - List.iter (fun cf -> + if not deep then List.iter (fun cf -> ignore(follow cf.cf_type); if has_class_field_flag cf CfImpl && has_class_field_flag cf CfEnum then match cf.cf_expr with | Some e -> - begin match extract_const e with - | Some ct -> if ct <> TNull then add (ConConst ct,null_pos) + begin match extract_ctor e with + | Some ctor -> add (ctor,null_pos) | None -> add (ConStatic(c,cf),null_pos) end; | _ -> add (ConStatic(c,cf),null_pos) ) c.cl_ordered_statics; - SKValue,CompileTimeFinite + let real_kind,_ = loop true (Abstract.get_underlying_type a pl) in + real_kind,CompileTimeFinite | TAbstract(a,pl) when not (Meta.has Meta.CoreType a.a_meta) -> - loop (Abstract.get_underlying_type a pl) + loop deep (Abstract.get_underlying_type a pl) | TInst({cl_path=[],"String"},_) | TInst({cl_kind = KTypeParameter _ },_) -> SKValue,Infinite | TInst({cl_path=[],"Array"},_) -> SKLength,Infinite | TEnum(en,pl) -> - PMap.iter (fun _ ef -> add (ConEnum(en,ef),null_pos)) en.e_constrs; + if not deep then + PMap.iter (fun _ ef -> add (ConEnum(en,ef),null_pos)) en.e_constrs; SKEnum,RunTimeFinite | TAnon _ -> SKValue,Infinite @@ -151,7 +156,7 @@ let all_ctors ctx e cases = | _ -> SKValue,Infinite in - let kind,finiteness = loop t in + let kind,finiteness = loop false t in let compatible_kind con = match fst con with | ConEnum _ -> kind = SKEnum | ConArray _ -> kind = SKLength @@ -168,12 +173,12 @@ let report_not_exhaustive v_lookup e_subject unmatched = let sl = match follow e_subject.etype with | TAbstract({a_impl = Some c} as a,tl) when a.a_enum -> List.map (fun (con,_) -> match fst con with - | ConConst ct1 -> + | ConConst _ | ConEnum _ -> let cf = List.find (fun cf -> match cf.cf_expr with | Some e -> - begin match extract_const e with - | Some ct2 -> ct1 = ct2 + begin match extract_ctor e with + | Some ctor -> Constructor.equal (ctor,null_pos) con | None -> false end | _ -> false diff --git a/tests/misc/projects/Issue11231/Main.hx b/tests/misc/projects/Issue11231/Main.hx new file mode 100644 index 00000000000..0b35decc42c --- /dev/null +++ b/tests/misc/projects/Issue11231/Main.hx @@ -0,0 +1,21 @@ +enum Ordering { + EQ; + LT; + GT; + } + +@:publicFields +enum abstract TriState(Ordering) from Ordering { + var True = GT; + var False = LT; + var Both = EQ; + + function icon():Int { + return switch (this : TriState) { + case True:1; + case Both:3; + } + } +} + +function main() {} \ No newline at end of file diff --git a/tests/misc/projects/Issue11231/Main2.hx b/tests/misc/projects/Issue11231/Main2.hx new file mode 100644 index 00000000000..e4c1619d49e --- /dev/null +++ b/tests/misc/projects/Issue11231/Main2.hx @@ -0,0 +1,22 @@ +enum Ordering { + EQ; + LT; + GT; + } + +@:publicFields +enum abstract TriState(Ordering) from Ordering { + var True = GT; + var False = LT; + var EvenFalser = LT; + var Both = EQ; + + function icon():Int { + return switch (this : TriState) { + case True:1; + case Both:3; + } + } +} + +function main() {} \ No newline at end of file diff --git a/tests/misc/projects/Issue11231/compile-fail.hxml b/tests/misc/projects/Issue11231/compile-fail.hxml new file mode 100644 index 00000000000..c098216e78e --- /dev/null +++ b/tests/misc/projects/Issue11231/compile-fail.hxml @@ -0,0 +1 @@ +Main diff --git a/tests/misc/projects/Issue11231/compile-fail.hxml.stderr b/tests/misc/projects/Issue11231/compile-fail.hxml.stderr new file mode 100644 index 00000000000..f0b126b3495 --- /dev/null +++ b/tests/misc/projects/Issue11231/compile-fail.hxml.stderr @@ -0,0 +1 @@ +Main.hx:14: characters 17-34 : Unmatched patterns: False \ No newline at end of file diff --git a/tests/misc/projects/Issue11231/compile2-fail.hxml b/tests/misc/projects/Issue11231/compile2-fail.hxml new file mode 100644 index 00000000000..e1a65dfa06d --- /dev/null +++ b/tests/misc/projects/Issue11231/compile2-fail.hxml @@ -0,0 +1 @@ +Main2 \ No newline at end of file diff --git a/tests/misc/projects/Issue11231/compile2-fail.hxml.stderr b/tests/misc/projects/Issue11231/compile2-fail.hxml.stderr new file mode 100644 index 00000000000..5be9ea490ff --- /dev/null +++ b/tests/misc/projects/Issue11231/compile2-fail.hxml.stderr @@ -0,0 +1 @@ +Main2.hx:15: characters 17-34 : Unmatched patterns: False \ No newline at end of file diff --git a/tests/unit/src/unit/issues/Issue11213.hx b/tests/unit/src/unit/issues/Issue11213.hx new file mode 100644 index 00000000000..14a9c98dc55 --- /dev/null +++ b/tests/unit/src/unit/issues/Issue11213.hx @@ -0,0 +1,30 @@ +package unit.issues; + +import utest.Assert; + +private enum Ordering { + EQ; + LT; + GT; +} + +@:publicFields +private enum abstract TriState(Ordering) from Ordering { + var True = GT; + var False = LT; + var Both = EQ; + + function icon():Int { + return switch (this : TriState) { + case True: 1; + case False: 2; + case Both: 3; + } + } +} + +class Issue11213 extends unit.Test { + function test() { + Assert.pass(); + } +}