Skip to content

Commit b7d8bb6

Browse files
chenmilliefacebook-github-bot
authored andcommitted
Error at classname variables in class member accesses and new
Summary: specifically, we warn against a `classname<_>` $c in `$c::f()`, `$c::X`, `$c::$x` and `new $c()` Reviewed By: vassilmladenov Differential Revision: D69555473 fbshipit-source-id: 7af548f1022d8d16b0d929281c38494d29de843b
1 parent ae9f969 commit b7d8bb6

File tree

11 files changed

+87
-3
lines changed

11 files changed

+87
-3
lines changed

hphp/hack/src/errors/error_codes.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,7 @@ module Typing = struct
777777
| InvalidRecursiveType [@value 4485]
778778
| StaticCallOnTraitRequireThisAs [@value 4486]
779779
| NeedsConcreteOverride [@value 4487]
780+
| StringToClassPointer [@value 4488]
780781
(* Add new Typing codes here! Comment out when deprecating. *)
781782
[@@deriving enum, show { with_path = false }]
782783

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

Lines changed: 2 additions & 1 deletion
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<<e55393123a98a4ee390186d6e756757f>>
6+
// @generated SignedSource<<e88a2f294b10a0e898cef421d353cb08>>
77
//
88
// To regenerate this file, run:
99
// hphp/hack/src/oxidized_regen.sh
@@ -601,6 +601,7 @@ pub enum Typing {
601601
InvalidRecursiveType = 4485,
602602
StaticCallOnTraitRequireThisAs = 4486,
603603
NeedsConcreteOverride = 4487,
604+
StringToClassPointer = 4488,
604605
}
605606
impl TrivialDrop for Typing {}
606607
arena_deserializer::impl_deserialize_in_arena!(Typing);

hphp/hack/src/typing/typing.ml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10049,7 +10049,20 @@ end = struct
1004910049
| (_, Tnewtype (classname, [the_cls], as_ty))
1005010050
when String.equal classname SN.Classes.cClassname ->
1005110051
let wrap ty = mk (Reason.none, Tnewtype (classname, [ty], as_ty)) in
10052-
resolve_class_pointer env wrap the_cls
10052+
let ((env, ty_err), (ty, err_res)) =
10053+
resolve_class_pointer env wrap the_cls
10054+
in
10055+
let cls_name =
10056+
Typing_print.full_strip_ns ~hide_internals:true env ty
10057+
in
10058+
Typing_class_pointers.error_at_classname_type
10059+
env
10060+
(TypecheckerOptions.class_pointer_level
10061+
(Env.get_tcopt env)
10062+
"classname_class")
10063+
p
10064+
cls_name;
10065+
((env, ty_err), (ty, err_res))
1005310066
| (_, Tclass_ptr the_cls) ->
1005410067
let wrap ty = mk (Reason.none, Tclass_ptr ty) in
1005510068
resolve_class_pointer env wrap the_cls

hphp/hack/src/typing/typing_class_pointers.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ let error_at_cls_ptr_type env level pos ty =
3232
Typing_error.(primary @@ Primary.Class_pointer_to_string { pos; ty })
3333
| _ -> ()
3434

35+
let error_at_classname_type env level pos cls_name =
36+
if level > 1 then
37+
Typing_error_utils.add_typing_error
38+
~env
39+
Typing_error.(
40+
primary @@ Primary.String_to_class_pointer { pos; cls_name })
41+
3542
let string_of_class_id_ = function
3643
| CIparent -> "parent"
3744
| CIself -> "self"

hphp/hack/src/typing/typing_error.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,6 +1359,10 @@ module Primary = struct
13591359
pos: Pos.t;
13601360
ty: string;
13611361
}
1362+
| String_to_class_pointer of {
1363+
pos: Pos.t;
1364+
cls_name: string;
1365+
}
13621366
| Optional_parameter_not_supported of Pos.t
13631367
| Optional_parameter_not_abstract of Pos.t
13641368
[@@deriving show]

hphp/hack/src/typing/typing_error.mli

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,10 @@ module Primary : sig
13351335
pos: Pos.t;
13361336
ty: string;
13371337
}
1338+
| String_to_class_pointer of {
1339+
pos: Pos.t;
1340+
cls_name: string;
1341+
}
13381342
| Optional_parameter_not_supported of Pos.t
13391343
| Optional_parameter_not_abstract of Pos.t
13401344
[@@deriving show]

hphp/hack/src/typing/typing_error_utils.ml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5520,6 +5520,25 @@ end = struct
55205520
[],
55215521
User_error_flags.empty )
55225522

5523+
let string_to_class_pointer pos cls_name =
5524+
let cls_name = Utils.strip_ns cls_name in
5525+
let classname_ty = Printf.sprintf "classname<%s>" cls_name in
5526+
let classname_ty_md = Markdown_lite.md_codify classname_ty in
5527+
let class_ptr_ty = Printf.sprintf "class<%s>" cls_name in
5528+
let class_ptr_ty_md = Markdown_lite.md_codify class_ptr_ty in
5529+
( Error_code.ClassPointerToString,
5530+
lazy
5531+
( pos,
5532+
"It is no longer allowed to use a "
5533+
^ classname_ty_md
5534+
^ " in this position. Please use a "
5535+
^ class_ptr_ty_md
5536+
^ " instead." ),
5537+
lazy [],
5538+
lazy Explanation.empty,
5539+
[],
5540+
User_error_flags.empty )
5541+
55235542
let to_error t ~env : error =
55245543
let open Typing_error.Primary in
55255544
match t with
@@ -6105,6 +6124,8 @@ end = struct
61056124
| Class_const_to_string { pos; cls_name } ->
61066125
class_const_to_string pos cls_name
61076126
| Class_pointer_to_string { pos; ty } -> class_pointer_to_string pos ty
6127+
| String_to_class_pointer { pos; cls_name } ->
6128+
string_to_class_pointer pos cls_name
61086129
| Optional_parameter_not_supported pos ->
61096130
optional_parameter_not_supported pos
61106131
| Optional_parameter_not_abstract pos -> optional_parameter_not_abstract pos
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
--config 'class_pointer_levels={"param": 2, "return": 2, "prop": 2, "concat": 2, "const": 2, "enum": 2, "arraykey": 3}'
1+
--config 'class_pointer_levels={"param": 2, "return": 2, "prop": 2, "concat": 2, "const": 2, "enum": 2, "arraykey": 3, "classname_class": 2}'
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?hh
2+
3+
<<__ConsistentConstruct>>
4+
class A {
5+
const string CNS = "X";
6+
public static int $prop = 42;
7+
public static function meth(): void {}
8+
}
9+
10+
class B extends A {
11+
public function test(classname<A> $a): void {
12+
$a::meth();
13+
$a::CNS;
14+
$a::$prop;
15+
new $a();
16+
}
17+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
ERROR: File "typing_error_classname.php", line 12, characters 5-6:
2+
It is no longer allowed to use a `classname<A>` in this position. Please use a `class<A>` instead. (Typing[4482])
3+
ERROR: File "typing_error_classname.php", line 13, characters 5-6:
4+
It is no longer allowed to use a `classname<A>` in this position. Please use a `class<A>` instead. (Typing[4482])
5+
ERROR: File "typing_error_classname.php", line 14, characters 5-6:
6+
It is no longer allowed to use a `classname<A>` in this position. Please use a `class<A>` instead. (Typing[4482])
7+
ERROR: File "typing_error_classname.php", line 15, characters 9-10:
8+
It is no longer allowed to use a `classname<A>` in this position. Please use a `class<A>` instead. (Typing[4482])

0 commit comments

Comments
 (0)