Skip to content

Commit ada6591

Browse files
Michael Thomasfacebook-github-bot
authored andcommitted
Consistently record provenance on lower bound
Summary: Extended reasons usually accumulates provenance on the subtype except for one case: when adding an upper bound to a type variable. This oversight was causing reasons to be dropped when we have an return type containing an invariant type variable. This diff modifies provenance generation so that we always accumulate on the lower bound during the transitivity step and makes the necessary change to the derivation generator to recognise nested lower bounds as a transitivity step. Reviewed By: patriciamckenzie Differential Revision: D63749923 fbshipit-source-id: af0f87c65e345721e824a33c52d0b8632a6762b1
1 parent 01223ea commit ada6591

30 files changed

+1820
-1827
lines changed

hphp/hack/src/oxidized/gen/typing_reason.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// This source code is licensed under the MIT license found in the
44
// LICENSE file in the "hack" directory of this source tree.
55
//
6-
// @generated SignedSource<<c6b91a87a00d2d2cbe95c809ceda6b2f>>
6+
// @generated SignedSource<<918b60cd8c49eefa45db8a2647a0d896>>
77
//
88
// To regenerate this file, run:
99
// hphp/hack/src/oxidized_regen.sh
@@ -601,13 +601,6 @@ pub enum T_ {
601601
/// Lift a typing-time witness into a reason
602602
#[rust_to_ocaml(name = "From_witness_locl")]
603603
FromWitnessLocl(WitnessLocl),
604-
/// Records that a type with reason [bound] acted as an upper bound
605-
/// for the type with reason [of_]
606-
#[rust_to_ocaml(name = "Upper_bound")]
607-
UpperBound {
608-
bound: Box<T_>,
609-
of__: Box<T_>,
610-
},
611604
/// Records that a type with reason [bound] acted as a lower bound
612605
/// for the type with reason [of_]
613606
#[rust_to_ocaml(name = "Lower_bound")]

hphp/hack/src/oxidized/manual/typing_reason_impl.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,7 @@ impl Reason {
129129
| ExprDepType(t, _, _)
130130
| Typeconst(t, _, _, _)
131131
| Instantiate(_, _, t) => t.pos(),
132-
UpperBound { .. }
133-
| LowerBound { .. }
132+
LowerBound { .. }
134133
| Flow { .. }
135134
| PrjBoth { .. }
136135
| PrjOne { .. }

hphp/hack/src/oxidized_by_ref/decl_visitor/node_impl_gen.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// This source code is licensed under the MIT license found in the
44
// LICENSE file in the "hack" directory of this source tree.
55
//
6-
// @generated SignedSource<<e9dc8d84abe0c00b2101757aaf332cfd>>
6+
// @generated SignedSource<<ee638d4fad5c87cb8e20e2ff970bb9be>>
77
//
88
// To regenerate this file, run:
99
// hphp/hack/src/oxidized_regen.sh
@@ -1306,15 +1306,6 @@ impl<'a> Node<'a> for T_<'a> {
13061306
T_::Instantiate(ref __binding_0) => __binding_0.accept(v),
13071307
T_::NoReason => {}
13081308
T_::FromWitnessLocl(ref __binding_0) => __binding_0.accept(v),
1309-
T_::UpperBound {
1310-
bound: ref __binding_0,
1311-
of__: ref __binding_1,
1312-
} => {
1313-
{
1314-
__binding_0.accept(v)
1315-
}
1316-
{ __binding_1.accept(v) }
1317-
}
13181309
T_::LowerBound {
13191310
bound: ref __binding_0,
13201311
of__: ref __binding_1,

hphp/hack/src/oxidized_by_ref/gen/typing_reason.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// This source code is licensed under the MIT license found in the
44
// LICENSE file in the "hack" directory of this source tree.
55
//
6-
// @generated SignedSource<<fee740c29d05ee32c91722b5cbb04967>>
6+
// @generated SignedSource<<20534e1077f6a68abb03a54b9f33e45a>>
77
//
88
// To regenerate this file, run:
99
// hphp/hack/src/oxidized_regen.sh
@@ -555,15 +555,6 @@ pub enum T_<'a> {
555555
#[serde(deserialize_with = "arena_deserializer::arena", borrow)]
556556
#[rust_to_ocaml(name = "From_witness_locl")]
557557
FromWitnessLocl(&'a WitnessLocl<'a>),
558-
/// Records that a type with reason [bound] acted as an upper bound
559-
/// for the type with reason [of_]
560-
#[rust_to_ocaml(name = "Upper_bound")]
561-
UpperBound {
562-
#[serde(deserialize_with = "arena_deserializer::arena", borrow)]
563-
bound: &'a T_<'a>,
564-
#[serde(deserialize_with = "arena_deserializer::arena", borrow)]
565-
of__: &'a T_<'a>,
566-
},
567558
/// Records that a type with reason [bound] acted as a lower bound
568559
/// for the type with reason [of_]
569560
#[rust_to_ocaml(name = "Lower_bound")]

hphp/hack/src/oxidized_by_ref/manual/typing_reason_impl.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,7 @@ impl<'a> std::fmt::Debug for T_<'a> {
193193
.finish(),
194194
DynamicCoercion(p) => f.debug_tuple("RdynamicCoercion").field(p).finish(),
195195
Invalid => f.debug_tuple("Rinvalid").finish(),
196-
UpperBound { .. }
197-
| LowerBound { .. }
196+
LowerBound { .. }
198197
| Flow { .. }
199198
| PrjBoth { .. }
200199
| PrjOne { .. }

hphp/hack/src/typing/typing_reason.ml

Lines changed: 7 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,13 +1402,6 @@ type _ t_ =
14021402
(* -- Core flow constructors -- *)
14031403
| From_witness_locl : witness_locl -> locl_phase t_
14041404
(** Lift a typing-time witness into a reason *)
1405-
| Upper_bound : {
1406-
bound: locl_phase t_;
1407-
of_: locl_phase t_;
1408-
}
1409-
-> locl_phase t_
1410-
(** Records that a type with reason [bound] acted as an upper bound
1411-
for the type with reason [of_] *)
14121405
| Lower_bound : {
14131406
bound: locl_phase t_;
14141407
of_: locl_phase t_;
@@ -1527,7 +1520,6 @@ let rec to_raw_pos : type ph. ph t_ -> Pos_or_decl.t =
15271520
(* Recurse into flow-like reasons to find the position of the leftmost witness *)
15281521
| Flow { from = t; _ }
15291522
| Lower_bound { bound = t; _ }
1530-
| Upper_bound { bound = t; _ }
15311523
| Axiom { next = t; _ }
15321524
| Prj_both { sub_prj = t; _ }
15331525
| Prj_one { part = t; _ }
@@ -1609,12 +1601,6 @@ let rec map_pos :
16091601
bound = map_pos pos pos_or_decl bound;
16101602
of_ = map_pos pos pos_or_decl of_;
16111603
}
1612-
| Upper_bound { bound; of_ } ->
1613-
Upper_bound
1614-
{
1615-
bound = map_pos pos pos_or_decl bound;
1616-
of_ = map_pos pos pos_or_decl of_;
1617-
}
16181604
| Axiom { prev; axiom; next } ->
16191605
Axiom
16201606
{
@@ -1660,7 +1646,6 @@ let to_constructor_string : type ph. ph t_ -> string = function
16601646
| From_witness_locl witness -> constructor_string_of_witness_locl witness
16611647
| From_witness_decl witness -> constructor_string_of_witness_decl witness
16621648
| Axiom _ -> "Raxiom"
1663-
| Upper_bound _ -> "Rupper_bound"
16641649
| Lower_bound _ -> "Rlower_bound"
16651650
| Flow _ -> "Rflow"
16661651
| Prj_both _ -> "Rprj_both"
@@ -1795,7 +1780,6 @@ let rec pp_t_ : type ph. _ -> ph t_ -> unit =
17951780
| Dynamic_coercion r -> pp_t_ fmt r
17961781
| Flow { from; _ } -> pp_t_ fmt from
17971782
| Axiom { next; _ } -> pp_t_ fmt next
1798-
| Upper_bound { bound; _ } -> pp_t_ fmt bound
17991783
| Lower_bound { bound; _ } -> pp_t_ fmt bound
18001784
| Prj_both { sub_prj; _ } -> pp_t_ fmt sub_prj
18011785
| Prj_one { part; _ } -> pp_t_ fmt part
@@ -1992,14 +1976,6 @@ let rec to_json_help : type a. a t_ -> Hh_json.json list -> Hh_json.json list =
19921976
] );
19931977
])
19941978
:: acc
1995-
| Upper_bound { bound; of_ } ->
1996-
Hh_json.(
1997-
JSON_Object
1998-
[
1999-
( "Upper_bound",
2000-
JSON_Object [("bound", to_json bound); ("of", to_json of_)] );
2001-
])
2002-
:: acc
20031979
| Lower_bound { bound; of_ } ->
20041980
Hh_json.(
20051981
JSON_Object
@@ -2097,7 +2073,6 @@ let rec to_string_help :
20972073
to_string_help prefix solutions r
20982074
| From_witness_locl witness -> [witness_locl_to_string prefix witness]
20992075
| From_witness_decl witness -> [witness_decl_to_string prefix witness]
2100-
| Upper_bound { bound = r; _ }
21012076
| Lower_bound { bound = r; _ }
21022077
| Axiom { next = r; _ }
21032078
| Def (_, r)
@@ -2552,8 +2527,6 @@ module Constructors = struct
25522527
let axiom_lower_bound ~bound ~of_ =
25532528
Axiom { axiom = Lower_bound; prev = of_; next = bound }
25542529

2555-
let trans_upper_bound ~bound ~of_ = Upper_bound { bound; of_ }
2556-
25572530
let trans_lower_bound ~bound ~of_ = Lower_bound { bound; of_ }
25582531

25592532
let definition def of_ = Def (def, of_)
@@ -2707,8 +2680,6 @@ module Visitor = struct
27072680
| Axiom { prev; axiom; next } ->
27082681
Axiom
27092682
{ prev = this#on_reason prev; axiom; next = this#on_reason next }
2710-
| Upper_bound { bound; of_ } ->
2711-
Upper_bound { bound = this#on_reason bound; of_ = this#on_reason of_ }
27122683
| Lower_bound { bound; of_ } ->
27132684
Lower_bound { bound = this#on_reason bound; of_ = this#on_reason of_ }
27142685
| Solved { solution; of_; in_ } ->
@@ -3237,10 +3208,6 @@ module Derivation = struct
32373208
bound: t;
32383209
in_: t;
32393210
}
3240-
| Upper of {
3241-
bound: t;
3242-
in_: t;
3243-
}
32443211
| Transitive of {
32453212
lower: t;
32463213
upper: t;
@@ -3252,19 +3219,13 @@ module Derivation = struct
32523219

32533220
let transitive ~upper ~lower ~on_ ~in_ = Transitive { in_; on_; upper; lower }
32543221

3255-
let upper_bound ~bound ~in_ = Upper { bound; in_ }
3256-
32573222
let lower_bound ~bound ~in_ = Lower { bound; in_ }
32583223

32593224
let to_json t =
32603225
let rec aux = function
32613226
| Derivation steps ->
32623227
Hh_json.(
32633228
JSON_Object [("Derivation", array_ Subtype_step.to_json steps)])
3264-
| Upper { bound; in_ } ->
3265-
Hh_json.(
3266-
JSON_Object
3267-
[("Upper", JSON_Object [("bound", aux bound); ("in_", aux in_)])])
32683229
| Lower { bound; in_ } ->
32693230
Hh_json.(
32703231
JSON_Object
@@ -3325,7 +3286,6 @@ module Derivation = struct
33253286
| Axiom { prev; _ } -> extract_last prev
33263287
| Flow { into; _ } -> extract_last into
33273288
| Lower_bound { of_; _ } -> extract_last of_
3328-
| Upper_bound { of_; _ } -> extract_last of_
33293289
| Solved _
33303290
| No_reason
33313291
| From_witness_decl _
@@ -3358,7 +3318,6 @@ module Derivation = struct
33583318
| Axiom { next; _ } -> extract_first next
33593319
| Flow { from; _ } -> extract_first from
33603320
| Lower_bound { bound; _ } -> extract_first bound
3361-
| Upper_bound { bound; _ } -> extract_first bound
33623321
| Solved _
33633322
| No_reason
33643323
| From_witness_decl _
@@ -3405,8 +3364,12 @@ module Derivation = struct
34053364
let solutions = Tvid.Map.add of_ (extract_first solution) solutions in
34063365
aux (sub, in_) ~deriv ~solutions
34073366
(* -- Transitive constraints -- *)
3408-
| ( Lower_bound { bound = lb_sub; of_ = lb_super },
3409-
Upper_bound { bound = ub_super; of_ = ub_sub } ) ->
3367+
| ( Lower_bound
3368+
{
3369+
bound = Lower_bound { bound = lb_sub; of_ = lb_super };
3370+
of_ = ub_sub;
3371+
},
3372+
ub_super ) ->
34103373
let lower = aux (lb_sub, lb_super) ~deriv:[] ~solutions
34113374
and upper = aux (ub_sub, ub_super) ~deriv:[] ~solutions
34123375
and in_ = aux (lb_sub, ub_super) ~deriv ~solutions
@@ -3420,14 +3383,6 @@ module Derivation = struct
34203383
let bound = aux (bound, of_) ~deriv:[] ~solutions
34213384
and in_ = aux (sub, bound) ~deriv ~solutions in
34223385
lower_bound ~bound ~in_
3423-
| (sub, Upper_bound { bound; of_ }) ->
3424-
let bound = aux (of_, bound) ~deriv:[] ~solutions
3425-
and in_ = aux (sub, bound) ~deriv ~solutions in
3426-
upper_bound ~bound ~in_
3427-
| (Upper_bound { bound; of_ }, super) ->
3428-
let bound = aux (of_, bound) ~deriv:[] ~solutions
3429-
and in_ = aux (bound, super) ~deriv ~solutions in
3430-
upper_bound ~bound ~in_
34313386
(* -- One-sided projection on subtype -- *)
34323387
| (Prj_one { part; whole; prj }, _) ->
34333388
let step =
@@ -3785,36 +3740,6 @@ module Derivation = struct
37853740
@ with_prefix expl_lower ~prefix:prefix_lower ~sep:"\n\n"
37863741
in
37873742
(expl, st)
3788-
| Upper { bound; in_ } ->
3789-
let (expl_main, st) =
3790-
explain in_ ~st ~cfg ~ctxt:(Context.enter_main ctxt)
3791-
in
3792-
let ctxt = Context.deepen ctxt in
3793-
let (expl_upper, st) =
3794-
explain bound ~st ~cfg ~ctxt:(Context.enter_upper ctxt)
3795-
in
3796-
3797-
let main_path =
3798-
Context.(Option.value_exn @@ explain_path @@ enter_main ctxt)
3799-
in
3800-
let prefix_main =
3801-
Format.sprintf
3802-
"I checked the subtype constraint in [%s] because it was implied by transitivity."
3803-
main_path
3804-
and prefix_upper =
3805-
let upper_path =
3806-
Context.(Option.value_exn @@ explain_path @@ enter_upper ctxt)
3807-
in
3808-
Format.sprintf
3809-
"I found the supertype for [%s] is when I checked the subtype constraint in [%s]."
3810-
main_path
3811-
upper_path
3812-
in
3813-
let expl =
3814-
with_prefix expl_main ~prefix:prefix_main ~sep:"\n\n"
3815-
@ with_prefix expl_upper ~prefix:prefix_upper ~sep:"\n\n"
3816-
in
3817-
(expl, st)
38183743

38193744
and explain_steps steps ~st ~cfg ~ctxt =
38203745
let steps =
@@ -3971,9 +3896,7 @@ module Derivation = struct
39713896
since we can have `Prj_one` in both subtype and supertype or
39723897
`Prj_both` as subtype and `Prj_one` in supertype and we will always
39733898
follow `Prj_one` before moving into `Prj_both` *)
3974-
| Lower_bound { of_; _ }
3975-
| Upper_bound { of_; _ } ->
3976-
explain_reason of_ ~st ~cfg ~ctxt
3899+
| Lower_bound { of_; _ } -> explain_reason of_ ~st ~cfg ~ctxt
39773900
| Prj_both { sub_prj; _ } -> explain_reason sub_prj ~st ~cfg ~ctxt
39783901
| Prj_one { part; _ } -> explain_reason part ~st ~cfg ~ctxt
39793902
| Axiom { next; _ } -> explain_reason next ~st ~cfg ~ctxt

hphp/hack/src/typing/typing_reason.mli

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,6 @@ val axiom_lower_bound :
381381
val trans_lower_bound :
382382
bound:locl_phase t_ -> of_:locl_phase t_ -> locl_phase t_
383383

384-
val trans_upper_bound :
385-
bound:locl_phase t_ -> of_:locl_phase t_ -> locl_phase t_
386-
387384
val definition : Pos_or_decl.t -> locl_phase t_ -> locl_phase t_
388385

389386
(** Record the decomposition of a covariant type parameter when simplifying a

hphp/hack/src/typing/typing_subtype.ml

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7832,10 +7832,6 @@ end = struct
78327832
(r_sub, var_sub)
78337833
cty_super
78347834
(on_error : Typing_error.Reasons_callback.t option) =
7835-
let cty_super =
7836-
Typing_env.update_cty_reason env cty_super ~f:(fun bound ->
7837-
Typing_reason.trans_upper_bound ~bound ~of_:r_sub)
7838-
in
78397835
let ty_super = ConstraintType cty_super in
78407836
let upper_bounds_before = Env.get_tyvar_upper_bounds env var_sub in
78417837
let env =
@@ -7885,6 +7881,10 @@ end = struct
78857881
in
78867882
List.fold_left
78877883
~f:(fun (env, prop1) lower_bound ->
7884+
let lower_bound =
7885+
Typing_env.update_reason env lower_bound ~f:(fun bound ->
7886+
Typing_reason.trans_lower_bound ~bound ~of_:r_sub)
7887+
in
78887888
(* Since we can have either the rhs of a subtype constraint or
78897889
the rhs of any other constraint in the upper bounds we
78907890
have to inspect the upper bound and dispatch to the
@@ -7917,10 +7917,6 @@ end = struct
79177917
ty_super
79187918
(on_error : Typing_error.Reasons_callback.t option) =
79197919
let ty_super = Sd.transform_dynamic_upper_bound ~coerce env ty_super in
7920-
let ty_super =
7921-
Typing_env.update_reason env ty_super ~f:(fun bound ->
7922-
Typing_reason.trans_upper_bound ~bound ~of_:r_sub)
7923-
in
79247920
let upper_bounds_before = Env.get_tyvar_upper_bounds env var in
79257921
let env =
79267922
Env.add_tyvar_upper_bound_and_update_variances
@@ -7970,12 +7966,16 @@ end = struct
79707966
in
79717967
List.fold_left
79727968
~f:(fun (env, prop1) lower_bound ->
7969+
let ty_sub =
7970+
Typing_env.update_reason env lower_bound ~f:(fun bound ->
7971+
Typing_reason.trans_lower_bound ~bound ~of_:r_sub)
7972+
in
79737973
let (env, prop2) =
79747974
Subtype.(
79757975
simplify
79767976
~subtype_env
79777977
~this_ty:None
7978-
~lhs:{ sub_supportdyn = None; ty_sub = lower_bound }
7978+
~lhs:{ sub_supportdyn = None; ty_sub }
79797979
~rhs:
79807980
{
79817981
super_like = false;
@@ -8225,6 +8225,7 @@ end = struct
82258225
and tell_cstr env (coerce, ty_sub, ty_super) on_error =
82268226
let (env, ty_sub) = Env.expand_internal_type env ty_sub in
82278227
let (env, ty_super) = Env.expand_internal_type env ty_super in
8228+
82288229
match (ty_sub, ty_super) with
82298230
| (LoclType lty_sub, LoclType lty_super) -> begin
82308231
match (get_node lty_sub, get_node lty_super) with

0 commit comments

Comments
 (0)