Skip to content

Commit

Permalink
Avoid generating expression-dependent type when it's safe to do so
Browse files Browse the repository at this point in the history
Summary:
Expression-dependent types are necessary only for classes that EITHER define abstract type constants (which can be realized by distinct types in subclasses) OR have methods that make use of `this` in their signatures (because these can be realized by distinct types in subclasses). Unfortunately, there is nothing at the class level that flags this property, but for well-known built-in classes such as `vec` and `dict` we can avoid generating an expression-dependent type.

Comments welcome on how we might generalize this.

Reviewed By: mheiber, madgen

Differential Revision: D53920324

fbshipit-source-id: e68445d1155cbc40c364faba7a0536da25e4a6f0
  • Loading branch information
Andrew Kennedy authored and facebook-github-bot committed Feb 23, 2024
1 parent 80b0b84 commit 51b81f1
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 11 deletions.
6 changes: 6 additions & 0 deletions hphp/hack/src/typing/typing_dependent_type.ml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ module ExprDepTy = struct
let (env, ty) = Env.expand_type env ty in
match deref ty with
| (_, Tclass (_, Exact, _)) -> (env, ty)
(* Special case for known final generic types that don't use this in their API *)
| (_, Tclass ((_, x), _, _))
when String.equal x Naming_special_names.Collections.cVec
|| String.equal x Naming_special_names.Collections.cDict
|| String.equal x Naming_special_names.Collections.cKeyset ->
(env, ty)
| (_, Tclass (((_, x) as c), Nonexact _, tyl)) ->
let class_ = Env.get_class env x in
(* If a class is both final and variant, we must treat it as non-final
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,25 @@ Invalid argument (Typing[4110])
File "subtype_supportdynamic.bad.php", line 3, characters 12-30:
Expected `dynamic`
File "subtype_supportdynamic.bad.php", line 13, characters 39-44:
Type `<expr#3> as vec<C>` is not a subtype of `dynamic` under dynamic-aware subtyping
Type `vec<C>` is not a subtype of `dynamic` under dynamic-aware subtyping
File "subtype_supportdynamic.bad.php", line 18, characters 5-7:
Invalid argument (Typing[4110])
File "subtype_supportdynamic.bad.php", line 3, characters 12-30:
Expected `dynamic`
File "subtype_supportdynamic.bad.php", line 13, characters 50-64:
Type `<expr#4> as dict<string, C>` is not a subtype of `dynamic` under dynamic-aware subtyping
Type `dict<string, C>` is not a subtype of `dynamic` under dynamic-aware subtyping
File "subtype_supportdynamic.bad.php", line 19, characters 5-7:
Invalid argument (Typing[4110])
File "subtype_supportdynamic.bad.php", line 3, characters 12-30:
Expected `dynamic`
File "subtype_supportdynamic.bad.php", line 14, characters 23-41:
Type `<expr#5> as dict<arraykey, C>` is not a subtype of `dynamic` under dynamic-aware subtyping
Type `dict<arraykey, C>` is not a subtype of `dynamic` under dynamic-aware subtyping
File "subtype_supportdynamic.bad.php", line 20, characters 5-7:
Invalid argument (Typing[4110])
File "subtype_supportdynamic.bad.php", line 3, characters 12-30:
Expected `dynamic`
File "subtype_supportdynamic.bad.php", line 15, characters 23-31:
Type `<expr#6> as vec<C>` is not a subtype of `dynamic` under dynamic-aware subtyping
Type `vec<C>` is not a subtype of `dynamic` under dynamic-aware subtyping
File "subtype_supportdynamic.bad.php", line 24, characters 5-6:
Invalid argument (Typing[4110])
File "subtype_supportdynamic.bad.php", line 3, characters 12-30:
Expand All @@ -63,13 +63,13 @@ Invalid argument (Typing[4110])
File "subtype_supportdynamic.bad.php", line 3, characters 12-30:
Expected `dynamic`
File "subtype_supportdynamic.bad.php", line 28, characters 33-38:
Type `<expr#2> as vec<C>` is not a subtype of `dynamic` under dynamic-aware subtyping
Type `vec<C>` is not a subtype of `dynamic` under dynamic-aware subtyping
File "subtype_supportdynamic.bad.php", line 33, characters 5-6:
Invalid argument (Typing[4110])
File "subtype_supportdynamic.bad.php", line 3, characters 12-30:
Expected `dynamic`
File "subtype_supportdynamic.bad.php", line 29, characters 33-44:
Type `<expr#3> as dict<int, C>` is not a subtype of `dynamic` under dynamic-aware subtyping
Type `dict<int, C>` is not a subtype of `dynamic` under dynamic-aware subtyping
File "subtype_supportdynamic.bad.php", line 37, characters 5-6:
Invalid argument (Typing[4110])
File "subtype_supportdynamic.bad.php", line 3, characters 12-30:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
File "simplify_unions.php", line 10, characters 3-13:
(<expr#2> as vec<C> | vec<nothing>)
vec<C>
No errors
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
File "simplify_unions.php", line 10, characters 3-13:
~(<expr#2> as vec<C> | vec<nothing>)
~vec<C>
No errors
4 changes: 1 addition & 3 deletions hphp/hack/test/typecheck/typedef17.php.imp_pess_exp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,4 @@ Invalid argument (Typing[4110])
File "typedef17.php", line 14, characters 26-29:
Expected `~vec<_>`
File "typedef17.php", line 22, characters 13-20:
But got `<expr#2> as vec<int>`
File "typedef17.php", line 23, characters 6-7:
where `<expr#2>` is a reference to this expression
But got `vec<int>`

0 comments on commit 51b81f1

Please sign in to comment.