Skip to content

Commit

Permalink
add parser code for lambda types
Browse files Browse the repository at this point in the history
  • Loading branch information
brmataptos committed Oct 3, 2024
1 parent ad600f0 commit 2b0551c
Show file tree
Hide file tree
Showing 43 changed files with 652 additions and 411 deletions.
2 changes: 1 addition & 1 deletion third_party/move/evm/move-to-yul/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ impl<'a> Context<'a> {
Tuple(_)
| TypeParameter(_)
| Reference(_, _)
| Fun(_, _)
| Fun(..)
| TypeDomain(_)
| ResourceDomain(_, _, _)
| Error
Expand Down
2 changes: 1 addition & 1 deletion third_party/move/evm/move-to-yul/src/solidity_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ impl SolidityType {
},
TypeParameter(_)
| Reference(_, _)
| Fun(_, _)
| Fun(..)
| TypeDomain(_)
| ResourceDomain(_, _, _)
| Error
Expand Down
38 changes: 24 additions & 14 deletions third_party/move/move-compiler-v2/src/bytecode_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ impl<'env> Generator<'env> {
self.emit_with(*id, |attr| Bytecode::SpecBlock(attr, spec));
},
// TODO(LAMBDA)
ExpData::Lambda(id, _, _) => self.error(
ExpData::Lambda(id, _, _, _) => self.error(
*id,
"Function-typed values not yet supported except as parameters to calls to inline functions",
),
Expand Down Expand Up @@ -1331,9 +1331,12 @@ impl<'env> Generator<'env> {
};
self.gen_borrow_field_operation(id, borrow_dest, str, fields, oper_temp);
if need_read_ref {
self.emit_call(id, vec![target], BytecodeOperation::ReadRef, vec![
borrow_dest,
])
self.emit_call(
id,
vec![target],
BytecodeOperation::ReadRef,
vec![borrow_dest],
)
}
}

Expand Down Expand Up @@ -1521,10 +1524,13 @@ enum MatchMode {
impl MatchMode {
/// Whether this match is in probing mode.
fn is_probing(&self) -> bool {
matches!(self, MatchMode::Refutable {
probing_vars: Some(_),
..
})
matches!(
self,
MatchMode::Refutable {
probing_vars: Some(_),
..
}
)
}

/// Whether a variable appearing in the pattern should be bound to a temporary.
Expand Down Expand Up @@ -1652,9 +1658,12 @@ impl<'env> Generator<'env> {
ReferenceKind::Immutable,
Box::new(value_ty.clone()),
));
self.emit_call(id, vec![value_ref], BytecodeOperation::BorrowLoc, vec![
value,
]);
self.emit_call(
id,
vec![value_ref],
BytecodeOperation::BorrowLoc,
vec![value],
);
needs_probing = true;
value_ref
}
Expand Down Expand Up @@ -1776,10 +1785,11 @@ impl<'env> Generator<'env> {
),
);
return Some(
ExpData::Call(id, Operation::Deref, vec![ExpData::LocalVar(
new_id, var,
ExpData::Call(
id,
Operation::Deref,
vec![ExpData::LocalVar(new_id, var).into_exp()],
)
.into_exp()])
.into_exp(),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ fn find_possibly_modified_vars(
_ => {},
}
},
Lambda(node_id, pat, _) => {
Lambda(node_id, pat, _, _) => {
// Define a new scope for bound vars, and turn off `modifying` within.
match pos {
VisitorPosition::Pre => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ impl<'env, 'params> SymbolVisitor<'env, 'params> {
Pre | Post | BeforeBody | MidMutate | BeforeThen | BeforeElse
| PreSequenceValue => {},
},
Lambda(_, pat, _) => {
Lambda(_, pat, _, _) => {
match position {
Pre => self.seen_uses.enter_scope(),
Post => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fn identify_function_types_with_functions_in_args(func_types: Vec<Type>) -> Vec<
func_types
.into_iter()
.filter_map(|ty| {
if let Type::Fun(argt, _) = &ty {
if let Type::Fun(argt, _, _) = &ty {
if argt.deref().has_function() {
Some(ty)
} else {
Expand All @@ -41,7 +41,7 @@ fn identify_function_typed_params_with_functions_in_rets(
func_types
.iter()
.filter_map(|param| {
if let Type::Fun(_argt, rest) = &param.1 {
if let Type::Fun(_argt, rest, _) = &param.1 {
let rest_unboxed = rest.deref();
if rest_unboxed.has_function() {
Some((*param, rest_unboxed))
Expand Down Expand Up @@ -270,7 +270,7 @@ fn check_privileged_operations_on_structs(env: &GlobalEnv, fun_env: &FunctionEnv
},
ExpData::Assign(_, pat, _)
| ExpData::Block(_, pat, _, _)
| ExpData::Lambda(_, pat, _) => {
| ExpData::Lambda(_, pat, _, _) => {
pat.visit_pre_post(&mut |_, pat| {
if let Pattern::Struct(id, str, _, _) = pat {
let module_id = str.module_id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1156,7 +1156,7 @@ impl<'env, 'rewriter> ExpRewriterFunctions for InlinedRewriter<'env, 'rewriter>
};
let call_loc = self.env.get_node_loc(id);
if let Some(lambda_target) = optional_lambda_target {
if let ExpData::Lambda(_, pat, body) = lambda_target.as_ref() {
if let ExpData::Lambda(_, pat, body, _) = lambda_target.as_ref() {
let args_vec: Vec<Exp> = args.to_vec();
Some(InlinedRewriter::construct_inlined_call_expression(
self.env,
Expand Down
44 changes: 30 additions & 14 deletions third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
//! ```

use itertools::Itertools;
use move_binary_format::file_format::AbilitySet;
use move_binary_format::file_format::Visibility;
use move_model::{
ast::{Exp, ExpData, Operation, Pattern, TempIndex},
Expand Down Expand Up @@ -259,10 +260,13 @@ impl<'a> ExpRewriterFunctions for LambdaLifter<'a> {

fn rewrite_assign(&mut self, _node_id: NodeId, lhs: &Pattern, _rhs: &Exp) -> Option<Exp> {
for (node_id, name) in lhs.vars() {
self.free_locals.insert(name, VarInfo {
node_id,
modified: true,
});
self.free_locals.insert(
name,
VarInfo {
node_id,
modified: true,
},
);
}
None
}
Expand All @@ -271,24 +275,36 @@ impl<'a> ExpRewriterFunctions for LambdaLifter<'a> {
if matches!(oper, Operation::Borrow(ReferenceKind::Mutable)) {
match args[0].as_ref() {
ExpData::LocalVar(node_id, name) => {
self.free_locals.insert(*name, VarInfo {
node_id: *node_id,
modified: true,
});
self.free_locals.insert(
*name,
VarInfo {
node_id: *node_id,
modified: true,
},
);
},
ExpData::Temporary(node_id, param) => {
self.free_params.insert(*param, VarInfo {
node_id: *node_id,
modified: true,
});
self.free_params.insert(
*param,
VarInfo {
node_id: *node_id,
modified: true,
},
);
},
_ => {},
}
}
None
}

fn rewrite_lambda(&mut self, id: NodeId, pat: &Pattern, body: &Exp) -> Option<Exp> {
fn rewrite_lambda(
&mut self,
id: NodeId,
pat: &Pattern,
body: &Exp,
_abilities: AbilitySet, // TODO(LAMBDA): do something with this
) -> Option<Exp> {
if self.exempted_lambdas.contains(&id) {
return None;
}
Expand Down Expand Up @@ -356,7 +372,7 @@ impl<'a> ExpRewriterFunctions for LambdaLifter<'a> {
let fun_name = self.gen_closure_function_name();
let lambda_loc = env.get_node_loc(id).clone();
let lambda_type = env.get_node_type(id);
let result_type = if let Type::Fun(_, result_type) = &lambda_type {
let result_type = if let Type::Fun(_, result_type, _) = &lambda_type {
*result_type.clone()
} else {
Type::Error // type error reported
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,18 @@ fn check_unused_params(struct_env: &StructEnv) {
for (i, TypeParameter(name, kind, loc)) in struct_env.get_type_parameters().iter().enumerate() {
if !kind.is_phantom && !used_params_in_fields.contains(&(i as u16)) {
let name = name.display(struct_env.symbol_pool());
env.diag_with_labels(Severity::Warning, loc, "unused type parameter", vec![(
loc.clone(),
format!(
"Unused type parameter `{}`. Consider declaring it as phantom",
name
),
)]);
env.diag_with_labels(
Severity::Warning,
loc,
"unused type parameter",
vec![(
loc.clone(),
format!(
"Unused type parameter `{}`. Consider declaring it as phantom",
name
),
)],
);
}
}
}
Expand All @@ -60,7 +65,7 @@ fn used_type_parameters_in_ty(ty: &Type) -> BTreeSet<u16> {
},
Type::TypeParameter(i) => BTreeSet::from([*i]),
Type::Vector(ty) => used_type_parameters_in_ty(ty),
Type::Fun(t1, t2) => [t1, t2]
Type::Fun(t1, t2, _) => [t1, t2]
.iter()
.flat_map(|t| used_type_parameters_in_ty(t))
.collect(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ impl ModuleGenerator {
ReferenceKind::Mutable => FF::SignatureToken::MutableReference(target_ty),
}
},
Fun(_param_ty, _result_ty) => {
Fun(_param_ty, _result_ty, _abilities) => {
// TODO(LAMBDA)
ctx.error(
loc,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@

Diagnostics:
error: unexpected token
┌─ tests/more-v1/parser/invalid_call_lhs_complex_expression.move:3:29
error: expected `|()|_` but found a value of type `integer`
┌─ tests/more-v1/parser/invalid_call_lhs_complex_expression.move:3:9
3 │ (if (true) 5 else 0)();
│ ^
│ │
│ Unexpected '('
│ Expected ';'
│ ^^^^^^^^^^^^^^^^^^^^^^

error: expected `|(integer, integer)|_` but found a value of type `()`
┌─ tests/more-v1/parser/invalid_call_lhs_complex_expression.move:4:9
4 │ (while (false) {})(0, 1);
│ ^^^^^^^^^^^^^^^^^^^^^^^^
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@

Diagnostics:
error: unexpected token
┌─ tests/more-v1/parser/invalid_call_lhs_complex_expression2.move:3:29
error: expected `|()|_` but found a value of type `integer`
┌─ tests/more-v1/parser/invalid_call_lhs_complex_expression2.move:3:9
3 │ (if (true) 5 else 0)();
│ ^
│ │
│ Unexpected '('
│ Expected ';'
│ ^^^^^^^^^^^^^^^^^^^^^^

error: expected `|(integer, integer)|_` but found a value of type `()`
┌─ tests/more-v1/parser/invalid_call_lhs_complex_expression2.move:4:9
4 │ (while (false) {})(0, 1);
│ ^^^^^^^^^^^^^^^^^^^^^^^^
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@

Diagnostics:
error: unexpected token
┌─ tests/more-v1/parser/invalid_call_lhs_parens_around_name.move:3:14
error: undeclared `foo`
┌─ tests/more-v1/parser/invalid_call_lhs_parens_around_name.move:3:10
3 │ (foo)()
│ ^
│ │
│ Unexpected '('
│ Expected ';'
│ ^^^
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@

Diagnostics:
error: unexpected token
┌─ tests/more-v1/parser/invalid_call_lhs_parens_around_name2.move:3:14
error: undeclared `foo`
┌─ tests/more-v1/parser/invalid_call_lhs_parens_around_name2.move:3:10
3 │ (foo)()
│ ^
│ │
│ Unexpected '('
│ Expected ';'
│ ^^^
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@

Diagnostics:
error: unexpected token
┌─ tests/more-v1/parser/invalid_call_lhs_return.move:3:20
error: Calls to function values other than inline function parameters not yet supported
┌─ tests/more-v1/parser/invalid_call_lhs_return.move:3:9
3 │ (return ())(0, 1);
│ ^
│ │
│ Unexpected '('
│ Expected ';'
│ ^^^^^^^^^^^
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@

Diagnostics:
error: unexpected token
┌─ tests/more-v1/parser/invalid_call_lhs_return2.move:3:20
error: Calls to function values other than inline function parameters not yet supported
┌─ tests/more-v1/parser/invalid_call_lhs_return2.move:3:9
3 │ (return ())(0, 1);
│ ^
│ │
│ Unexpected '('
│ Expected ';'
│ ^^^^^^^^^^^
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@

Diagnostics:
error: unexpected token
┌─ tests/more-v1/parser/invalid_call_lhs_value.move:3:10
error: expected `|()|_` but found a value of type `integer`
┌─ tests/more-v1/parser/invalid_call_lhs_value.move:3:9
3 │ 5();
│ ^
│ │
│ Unexpected '('
│ Expected ';'
│ ^^^

error: expected `|(integer, integer)|_` but found a value of type `integer`
┌─ tests/more-v1/parser/invalid_call_lhs_value.move:4:9
4 │ 5(0, 1);
│ ^^^^^^^
Loading

0 comments on commit 2b0551c

Please sign in to comment.