Skip to content

Commit

Permalink
Box shape types in a DSL type
Browse files Browse the repository at this point in the history
Summary: Introduce a type wrapper to box shape types during virtualization

Reviewed By: dlreeves

Differential Revision: D69315090

fbshipit-source-id: 7392ef1ef245fae5a38a47084edab912ba612c1d
  • Loading branch information
Michel Weststrate authored and facebook-github-bot committed Feb 10, 2025
1 parent c80c65d commit d8cbaaa
Show file tree
Hide file tree
Showing 43 changed files with 70 additions and 57 deletions.
1 change: 1 addition & 0 deletions hphp/hack/src/naming/naming_special_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1153,6 +1153,7 @@ pub mod expression_trees {
pub const VOID_TYPE: &str = "voidType";
pub const SYMBOL_TYPE: &str = "symbolType";
pub const LAMBDA_TYPE: &str = "lambdaType";
pub const SHAPE_TYPE: &str = "shapeType";

pub const VISIT_INT: &str = "visitInt";
pub const VISIT_FLOAT: &str = "visitFloat";
Expand Down
7 changes: 6 additions & 1 deletion hphp/hack/src/parser/lowerer/desugar_expression_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1618,7 +1618,12 @@ impl RewriteState {
));
}
}
let virtual_expr = Expr((), pos.clone(), Shape(virtual_shape_fields));
let virtual_expr = static_meth_call(
visitor_name,
et::SHAPE_TYPE,
vec![Expr((), pos.clone(), Shape(virtual_shape_fields))],
&pos,
);
let desugar_expr = v_meth_call(
et::VISIT_SHAPE,
vec![pos_expr, vec_literal(desugar_shape_fields)],
Expand Down
7 changes: 7 additions & 0 deletions hphp/hack/test/expr_tree.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ public static function symbolType<T>(
public static function lambdaType<T>(T $_): ExampleFunction<T> {
throw new Exception();
}
public static function shapeType<T>(T $_): ExampleShape<T> {
throw new Exception();
}

// Desugared nodes. Calls to these are emitted by hackc, following the structure
// of the expression in the expression tree. Here, they compute a string
Expand Down Expand Up @@ -383,6 +386,10 @@ interface ExampleFunction<T> {
public function __unwrap(): T;
}

interface ExampleShape<T> {
public function __unwrap(): T;
}

abstract class ExampleKeyedCollection<+Tkey as ExampleArraykey, +Tvalue> {
public static function __makeType<Tk as ExampleArraykey, Tv>(
(Tk, Tv) ...$_
Expand Down
2 changes: 1 addition & 1 deletion hphp/hack/test/expr_tree_debug_print/shape_param.good.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

function g(): void {
ExampleDsl`{
$f = (shape('x' => ExampleInt, 'y' => ExampleString) $shape) ==> 3;
$f = (ExampleShape<shape('x' => ExampleInt, 'y' => ExampleString)> $shape) ==> 3;
return $f(shape('x' => 3, 'y' => 'hello'));
}`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function g(): void {
darray["splices" => dict[], "functions" => vec[], "static_methods" => vec[]],
(
(ExampleDsl $v) ==> {
return $v->visitCall(darray["path" => __FILE__, "start_line" => 5, "end_line" => 8, "start_column" => 13, "end_column" => 3], $v->visitLambda(darray["path" => __FILE__, "start_line" => 5, "end_line" => 8, "start_column" => 13, "end_column" => 3], vec[], vec[$v->visitAssign(darray["path" => __FILE__, "start_line" => 6, "end_line" => 6, "start_column" => 4, "end_column" => 70], $v->visitLocal(darray["path" => __FILE__, "start_line" => 6, "end_line" => 6, "start_column" => 4, "end_column" => 6], "$f"), $v->visitLambda(darray["path" => __FILE__, "start_line" => 6, "end_line" => 6, "start_column" => 9, "end_column" => 70], vec["$shape"], vec[$v->visitReturn(darray["path" => __FILE__, "start_line" => 6, "end_line" => 6, "start_column" => 69, "end_column" => 70], $v->visitInt(darray["path" => __FILE__, "start_line" => 6, "end_line" => 6, "start_column" => 69, "end_column" => 70], 3))])), $v->visitReturn(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 4, "end_column" => 47], $v->visitCall(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 11, "end_column" => 46], $v->visitLocal(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 11, "end_column" => 13], "$f"), vec[$v->visitShape(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 14, "end_column" => 45], vec[varray[$v->visitString(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 20, "end_column" => 23], "x"), $v->visitInt(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 27, "end_column" => 28], 3)], varray[$v->visitString(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 30, "end_column" => 33], "y"), $v->visitString(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 37, "end_column" => 44], "hello")]])]))]), vec[]);
return $v->visitCall(darray["path" => __FILE__, "start_line" => 5, "end_line" => 8, "start_column" => 13, "end_column" => 3], $v->visitLambda(darray["path" => __FILE__, "start_line" => 5, "end_line" => 8, "start_column" => 13, "end_column" => 3], vec[], vec[$v->visitAssign(darray["path" => __FILE__, "start_line" => 6, "end_line" => 6, "start_column" => 4, "end_column" => 84], $v->visitLocal(darray["path" => __FILE__, "start_line" => 6, "end_line" => 6, "start_column" => 4, "end_column" => 6], "$f"), $v->visitLambda(darray["path" => __FILE__, "start_line" => 6, "end_line" => 6, "start_column" => 9, "end_column" => 84], vec["$shape"], vec[$v->visitReturn(darray["path" => __FILE__, "start_line" => 6, "end_line" => 6, "start_column" => 83, "end_column" => 84], $v->visitInt(darray["path" => __FILE__, "start_line" => 6, "end_line" => 6, "start_column" => 83, "end_column" => 84], 3))])), $v->visitReturn(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 4, "end_column" => 47], $v->visitCall(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 11, "end_column" => 46], $v->visitLocal(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 11, "end_column" => 13], "$f"), vec[$v->visitShape(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 14, "end_column" => 45], vec[varray[$v->visitString(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 20, "end_column" => 23], "x"), $v->visitInt(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 27, "end_column" => 28], 3)], varray[$v->visitString(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 30, "end_column" => 33], "y"), $v->visitString(darray["path" => __FILE__, "start_line" => 7, "end_line" => 7, "start_column" => 37, "end_column" => 44], "hello")]])]))]), vec[]);
}
),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ ERROR: File "async_generator.php", line 6, characters 29-35:
Some elements in this collection are incompatible (Typing[4110])
File "expr_tree.php", line 60, characters 21-26:
Expected `string`
File "expr_tree.php", line 165, characters 9-24:
File "expr_tree.php", line 168, characters 9-24:
resulting from expanding the type constant `ExampleDsl::TAst`
File "async_generator.php", line 6, characters 29-35:
But got `null` (`$generator->send()` can always send a `null` back to a `yield`)
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ERROR: File "await_in_tree.php", line 12, characters 14-39:
`await` can only be used inside `async` functions (NastCheck[3003])
ERROR: File "await_in_tree.php", line 12, characters 20-39:
This value cannot be inserted (spliced) into a `ExampleDsl` expression tree (Typing[4110])
File "expr_tree.php", line 320, characters 5-27:
File "expr_tree.php", line 323, characters 5-27:
Expected `ExampleDslExpression<T>` because you are splicing into a `ExampleDsl` expression or block
File "await_in_tree.php", line 6, characters 4-64:
But got `Awaitable<ExprTree<ExampleDsl, string, ExampleInt>>`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ERROR: File "await_in_tree.php", line 12, characters 14-39:
`await` can only be used inside `async` functions (NastCheck[3003])
ERROR: File "await_in_tree.php", line 12, characters 20-39:
This value cannot be inserted (spliced) into a `ExampleDsl` expression tree (Typing[4110])
File "expr_tree.php", line 320, characters 5-27:
File "expr_tree.php", line 323, characters 5-27:
Expected `ExampleDslExpression<T>` because you are splicing into a `ExampleDsl` expression or block
File "await_in_tree.php", line 6, characters 14-63:
But got `Awaitable<~ExprTree<ExampleDsl, string, ExampleInt>>`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ You are trying to access the method `__barbar` but this object can be null. (Typ
This can be null
ERROR: File "boolean_operators.php", line 28, characters 19-33:
Invalid argument (Typing[4110])
File "expr_tree.php", line 367, characters 28-38:
File "expr_tree.php", line 370, characters 28-38:
Expected `ExampleBool`
File "boolean_operators.php", line 7, characters 82-93:
But got `?ExampleBool`
Expand All @@ -14,7 +14,7 @@ You are trying to access the method `__ampamp` but this object can be null. (Typ
This can be null
ERROR: File "boolean_operators.php", line 33, characters 19-33:
Invalid argument (Typing[4110])
File "expr_tree.php", line 366, characters 28-38:
File "expr_tree.php", line 369, characters 28-38:
Expected `ExampleBool`
File "boolean_operators.php", line 7, characters 82-93:
But got `?ExampleBool`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ You are trying to access the method `__barbar` but this object can be null. (Typ
This can be null
ERROR: File "boolean_operators.php", line 28, characters 19-33:
Invalid argument (Typing[4110])
File "expr_tree.php", line 367, characters 28-38:
File "expr_tree.php", line 370, characters 28-38:
Expected `~ExampleBool`
File "boolean_operators.php", line 7, characters 82-93:
But got `?ExampleBool`
Expand All @@ -14,7 +14,7 @@ You are trying to access the method `__ampamp` but this object can be null. (Typ
This can be null
ERROR: File "boolean_operators.php", line 33, characters 19-33:
Invalid argument (Typing[4110])
File "expr_tree.php", line 366, characters 28-38:
File "expr_tree.php", line 369, characters 28-38:
Expected `~ExampleBool`
File "boolean_operators.php", line 7, characters 82-93:
But got `?ExampleBool`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ ERROR: File "coeffects.php", line 20, characters 14-21:
This call is not allowed because its capabilities are incompatible with the context (Typing[4390])
File "coeffects.php", line 14, characters 16-17:
From this declaration, the context of this function body provides the capability set {}
File "expr_tree.php", line 317, characters 19-24:
File "expr_tree.php", line 320, characters 19-24:
But the function being called requires the capability set {AccessGlobals, IO, ImplicitPolicyLocal, RxLocal, SystemLocal, WriteProperty}
ERROR: File "coeffects.php", line 20, characters 16-18:
This call is not allowed because its capabilities are incompatible with the context (Typing[4390])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ERROR: File "collection_error.php", line 6, characters 14-22:
Unbound name: `wrongCtor` (an object type) (Naming[2049])
ERROR: File "collection_error.php", line 7, characters 14-35:
Could not find `exampleKeyedCollection`. (Naming[2006])
File "expr_tree.php", line 386, characters 16-37:
File "expr_tree.php", line 393, characters 16-37:
Did you mean `~~E~~xampleKeyedCollection` instead (which only differs by case)?
ERROR: File "collection_error.php", line 11, characters 14-23:
Unbound name: `symbolType` (an object type) (Naming[2049])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ERROR: File "collection_error.php", line 6, characters 14-22:
Unbound name: `wrongCtor` (an object type) (Naming[2049])
ERROR: File "collection_error.php", line 7, characters 14-35:
Could not find `exampleKeyedCollection`. (Naming[2006])
File "expr_tree.php", line 386, characters 16-37:
File "expr_tree.php", line 393, characters 16-37:
Did you mean `~~E~~xampleKeyedCollection` instead (which only differs by case)?
ERROR: File "collection_error.php", line 11, characters 14-23:
Unbound name: `symbolType` (an object type) (Naming[2049])
Expand Down
2 changes: 1 addition & 1 deletion hphp/hack/test/typecheck/expression_trees/elvis.php.exp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ERROR: File "elvis.php", line 7, characters 19-33:
Invalid argument (Typing[4110])
File "expr_tree.php", line 60, characters 21-26:
Expected `string`
File "expr_tree.php", line 213, characters 6-21:
File "expr_tree.php", line 216, characters 6-21:
resulting from expanding the type constant `ExampleDsl::TAst`
File "elvis.php", line 7, characters 19-22:
But got `bool`
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ERROR: File "generator.php", line 6, characters 23-29:
Some elements in this collection are incompatible (Typing[4110])
File "expr_tree.php", line 60, characters 21-26:
Expected `string`
File "expr_tree.php", line 165, characters 9-24:
File "expr_tree.php", line 168, characters 9-24:
resulting from expanding the type constant `ExampleDsl::TAst`
File "generator.php", line 6, characters 23-29:
But got `null` (`$generator->send()` can always send a `null` back to a `yield`)
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ ERROR: File "invalid_operator.php", line 16, characters 19-26:
Invalid argument (Typing[4110])
File "expr_tree.php", line 60, characters 21-26:
Expected `string`
File "expr_tree.php", line 134, characters 5-20:
File "expr_tree.php", line 137, characters 5-20:
resulting from expanding the type constant `ExampleDsl::TAst`
File "invalid_operator.php", line 9, characters 7-9:
But got `int`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ ERROR: File "invalid_operator.php", line 16, characters 19-26:
Invalid argument (Typing[4110])
File "expr_tree.php", line 60, characters 21-26:
Expected `string`
File "expr_tree.php", line 134, characters 5-20:
File "expr_tree.php", line 137, characters 5-20:
resulting from expanding the type constant `ExampleDsl::TAst`
File "invalid_operator.php", line 9, characters 7-9:
But got `int`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ERROR: File "nested_expression_tree_lambda.php", line 6, characters 28-40:
Invalid argument (Typing[4110])
File "expr_tree.php", line 60, characters 21-26:
Expected `string`
File "expr_tree.php", line 205, characters 5-20:
File "expr_tree.php", line 208, characters 5-20:
resulting from expanding the type constant `ExampleDsl::TAst`
File "expr_tree.php", line 72, characters 8-53:
But got `ExprTree<ExampleDsl, string, ExampleInt>`
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ ERROR: File "parse_constants.php", line 8, characters 23-30:
Invalid argument (Typing[4110])
File "expr_tree.php", line 60, characters 21-26:
Expected `string`
File "expr_tree.php", line 136, characters 5-20:
File "expr_tree.php", line 139, characters 5-20:
resulting from expanding the type constant `ExampleDsl::TAst`
File "parse_constants.php", line 5, characters 7-9:
But got `int`
ERROR: File "parse_constants.php", line 8, characters 23-30:
Invalid argument (Typing[4110])
File "expr_tree.php", line 343, characters 26-35:
File "expr_tree.php", line 346, characters 26-35:
Expected `ExampleInt`
File "parse_constants.php", line 5, characters 7-9:
But got `int`
4 changes: 2 additions & 2 deletions hphp/hack/test/typecheck/expression_trees/pipe2.php.exp
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ Wrong number of type arguments (expected 0, got 3) (Typing[4101])
Definition is here
ERROR: File "pipe2.php", line 21, characters 30-52:
This value cannot be inserted (spliced) into a `ExampleDsl` expression tree (Typing[4110])
File "expr_tree.php", line 320, characters 5-27:
File "expr_tree.php", line 323, characters 5-27:
Expected `ExampleDslExpression<T>` because you are splicing into a `ExampleDsl` expression or block
File "pipe2.php", line 9, characters 70-124:
But got `ExampleDsl`
File "pipe2.php", line 21, characters 33-50:
Hack values need to be converted (lifted) to compatible types before splicing. For more information see: https://docs.hhvm.com/hack/expression-trees/splicing
ERROR: File "pipe2.php", line 21, characters 33-50:
Invalid argument (Typing[4110])
File "expr_tree.php", line 320, characters 5-27:
File "expr_tree.php", line 323, characters 5-27:
Expected `Spliceable<ExampleDsl, string, _>`
File "pipe2.php", line 9, characters 70-124:
But got `ExampleDsl`
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ Wrong number of type arguments (expected 0, got 3) (Typing[4101])
Definition is here
ERROR: File "pipe2.php", line 21, characters 30-52:
This value cannot be inserted (spliced) into a `ExampleDsl` expression tree (Typing[4110])
File "expr_tree.php", line 320, characters 5-27:
File "expr_tree.php", line 323, characters 5-27:
Expected `ExampleDslExpression<T>` because you are splicing into a `ExampleDsl` expression or block
File "pipe2.php", line 9, characters 70-124:
But got `~ExampleDsl` because the type of this return is implicitly a like-type due to unenforced generic type arguments
File "pipe2.php", line 21, characters 33-50:
Hack values need to be converted (lifted) to compatible types before splicing. For more information see: https://docs.hhvm.com/hack/expression-trees/splicing
ERROR: File "pipe2.php", line 21, characters 33-50:
Invalid argument (Typing[4110])
File "expr_tree.php", line 320, characters 5-27:
File "expr_tree.php", line 323, characters 5-27:
Expected `Spliceable<ExampleDsl, string, _>`
File "pipe2.php", line 9, characters 70-124:
But got `ExampleDsl`
4 changes: 2 additions & 2 deletions hphp/hack/test/typecheck/expression_trees/pipe5.php.exp
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ Wrong number of type arguments (expected 0, got 3) (Typing[4101])
Definition is here
ERROR: File "pipe5.php", line 17, characters 19-41:
This value cannot be inserted (spliced) into a `ExampleDsl` expression tree (Typing[4110])
File "expr_tree.php", line 320, characters 5-27:
File "expr_tree.php", line 323, characters 5-27:
Expected `ExampleDslExpression<T>` because you are splicing into a `ExampleDsl` expression or block
File "pipe5.php", line 9, characters 70-124:
But got `ExampleDsl`
File "pipe5.php", line 17, characters 22-39:
Hack values need to be converted (lifted) to compatible types before splicing. For more information see: https://docs.hhvm.com/hack/expression-trees/splicing
ERROR: File "pipe5.php", line 17, characters 22-39:
Invalid argument (Typing[4110])
File "expr_tree.php", line 320, characters 5-27:
File "expr_tree.php", line 323, characters 5-27:
Expected `Spliceable<ExampleDsl, string, _>`
File "pipe5.php", line 9, characters 70-124:
But got `ExampleDsl`
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ Wrong number of type arguments (expected 0, got 3) (Typing[4101])
Definition is here
ERROR: File "pipe5.php", line 17, characters 19-41:
This value cannot be inserted (spliced) into a `ExampleDsl` expression tree (Typing[4110])
File "expr_tree.php", line 320, characters 5-27:
File "expr_tree.php", line 323, characters 5-27:
Expected `ExampleDslExpression<T>` because you are splicing into a `ExampleDsl` expression or block
File "pipe5.php", line 9, characters 70-124:
But got `~ExampleDsl` because the type of this return is implicitly a like-type due to unenforced generic type arguments
File "pipe5.php", line 17, characters 22-39:
Hack values need to be converted (lifted) to compatible types before splicing. For more information see: https://docs.hhvm.com/hack/expression-trees/splicing
ERROR: File "pipe5.php", line 17, characters 22-39:
Invalid argument (Typing[4110])
File "expr_tree.php", line 320, characters 5-27:
File "expr_tree.php", line 323, characters 5-27:
Expected `Spliceable<ExampleDsl, string, _>`
File "pipe5.php", line 9, characters 70-124:
But got `ExampleDsl`
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ ERROR: File "property_access_error3.php", line 7, characters 13-19:
No property `my_prop` in `ExampleInt` (Typing[4053])
File "property_access_error3.php", line 13, characters 92-101:
This is why I think it is an object of type ExampleInt
File "expr_tree.php", line 342, characters 11-20:
File "expr_tree.php", line 345, characters 11-20:
Declaration of `ExampleInt` is here
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

<<file:__EnableUnstableFeatures('expression_trees')>>

type MyExampleShape = shape('y' => ExampleString);
type MyExampleShape = ExampleShape<shape('y' => ExampleString)>;

function g(): void {
ExampleDsl`{
$f = (shape('x' => ExampleInt) $shape) ==> 3;
$f = (ExampleShape<shape('x' => ExampleInt)> $shape) ==> 3;
$f(shape('x' => 2));
}`;

ExampleDsl`{
$f = (shape('x' => ExampleInt) $shape) ==> 3;
$f = (ExampleShape<shape('x' => ExampleInt)> $shape) ==> 3;
$x = shape('x' => 2);
$f($x);
}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

function g(): void {
ExampleDsl`{
$f = (shape('x' => ExampleInt, 'y' => ExampleString) $shape) ==> 3;
$f = (ExampleShape<shape('x' => ExampleInt, 'y' => ExampleString)> $shape) ==> 3;
$f(shape('x' => 2));
}`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ ERROR: File "shape_creation_missing_field.php", line 8, characters 8-22:
Invalid argument (Typing[4057])
File "shape_creation_missing_field.php", line 8, characters 8-22:
The field `y` is missing
File "shape_creation_missing_field.php", line 7, characters 36-38:
File "shape_creation_missing_field.php", line 7, characters 49-51:
The field `y` is defined
Loading

0 comments on commit d8cbaaa

Please sign in to comment.