-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[move-compiler-v2] Generate suitable error messages for current misuse of function-typed values, lay groundwork for implementing and testing more general lambdas. #14732
base: main
Are you sure you want to change the base?
Conversation
… values, lay groundwork for implementing and testing more general lambdas. Fixes #14633. Catch all errors in test/checking/typing/lambda.move in Compiler V2, after splitting and gradually commenting out code as lambda[2-5].move to avoid shadowing by other errors. - add checking for function-typed function results in `function_checker` - Change `internal_error` to `error` in `bytecode_generator` and `module_generator` to properly show "error" rather than "bug" if lambdas are mistakenly used as values today. - tag some code to show where changes are needed to support lambda: // TODO(LAMBDA) - fix unused_params_checker and recursive_struct_checker to tolerate lambda types - add experiments to control enabling of various aspects of lambda support: - LAMBDA_PARAMS, LAMBDA_RESULTS to allow lambdas as general function params or results - LAMBDA_FIELDS - support lambdas in struct fields - LAMBDA_VALUES - support lambdas in general-purpose values - may add LAMBDA_TYPE_PARAMS later - update lambda-lifting test config to use those flags rather than disabling checks - add a `result_type_loc` field to move-model's `FunctionData` (and model-builder's `FunEntry`) to more precisely locate errors in function result types. - Fix `GlobalEnv::internal_dump_env` to use function- and struct-specific type contexts so that types are shown with correct type parameter names. - Check that struct fields are not functions.
⏱️ 29m total CI duration on this PR
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #14732 +/- ##
===========================================
- Coverage 71.9% 59.8% -12.1%
===========================================
Files 2395 852 -1543
Lines 482134 207572 -274562
===========================================
- Hits 346822 124307 -222515
+ Misses 135312 83265 -52047
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
@@ -552,6 +567,7 @@ impl Constraint { | |||
Constraint::NoPhantom, | |||
Constraint::NoReference, | |||
Constraint::NoTuple, | |||
Constraint::NoFunction, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will we not support a vector of lambdas (of the same function type)? Or is this a short-term limitation that might be lifted later (if so, a todo might be good)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is fairly self-evident. Note that someday we may support references or tuples in type parameters and/or vectors, but there are no TODOs there. But I'm adding a comment.
@@ -3977,6 +3979,9 @@ pub struct FunctionData { | |||
/// Location of the function identifier, suitable for error messages alluding to the function. | |||
pub(crate) id_loc: Loc, | |||
|
|||
/// Location of the function result type, suitable for error messages alluding to the result type. | |||
pub(crate) result_type_loc: Loc, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: since we have 3 fields to track various locations pertaining to a function, may be it should be its own struct (in case we want to further extend it)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kind of nitty. But I''m doing that.
|
||
public fun fun_arg_lambda_not_allowed(x: |u64|) {} // expected lambda not allowed | ||
|
||
public inline fun macro_result_lambda_not_allowed(): |u64| { // expected lambda not allowed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public inline fun macro_result_lambda_not_allowed(): |u64| { // expected lambda not allowed | |
public inline fun inline_result_lambda_not_allowed(): |u64| { // expected lambda not allowed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we only call assert!
a macro currently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test case came from existing test lambda.move.
module 0x8675309::M { | ||
// use 0x1::XVector; | ||
|
||
// public inline fun foreach<T>(v: &vector<T>, action: |&T|) { // expected to be not implemented |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We seem to have a lot of commented code in this test. Should it be removed? If not, would be good to leave some notes as to why the commented out code should be left around.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm adding a comment at the top to try to clarify what we're doing:
// *** NOTE: THIS TEST FILE IS DERIVED FROM lambda.move by commenting out code which has errors
// successfully flagged by move-compiler-v2, so that we can check for errors on other lines
// which may be shadowed by those errors.
//
// We keep the commented code so that the error line numbers line up.
//
//
// ... code removed here to allow above message ...
//
Hopefully that is sufficient.
┌─ tests/move_check/typing/lambda2.move:77:18 | ||
│ | ||
77 │ let _x = |i| i + 1; // expected lambda not allowed | ||
│ ^^^^^^^^^ function type only allowed for inline function arguments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a function value and not function type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to "function-typed values" here.
let _x = |i| i + 1; // expected lambda not allowed | ||
} | ||
|
||
// struct FieldFunNotAllowed { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this commented out? Don't we want some of this to be checked here?
module 0x8675309::M { | ||
// use 0x1::XVector; | ||
|
||
// public inline fun foreach<T>(v: &vector<T>, action: |&T|) { // expected to be not implemented |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uncomment or remove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a comment at the top to explain what we're doing here, commenting out lines to suppress errors that were shown for lambda2.move, so that shadowed errors can be revealed while keeping line numbers identical to facilitate output matching with V1.
|
||
// public fun fun_arg_lambda_not_allowed(x: |u64|) {} // expected lambda not allowed | ||
|
||
public inline fun macro_result_lambda_not_allowed(): |u64| { // expected lambda not allowed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public inline fun macro_result_lambda_not_allowed(): |u64| { // expected lambda not allowed | |
public inline fun inline_result_lambda_not_allowed(): |u64| { // expected lambda not allowed |
module 0x8675309::M { | ||
// use 0x1::XVector; | ||
|
||
// public inline fun foreach<T>(v: &vector<T>, action: |&T|) { // expected to be not implemented |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I understand the logic behind having multiple test files with a bunch of code commented out and some code uncommented. Maybe these could be split into multiple test files without duplication?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See responses elsewhere.
module 0x8675309::M { | ||
// use 0x1::XVector; | ||
|
||
// public inline fun foreach<T>(v: &vector<T>, action: |&T|) { // expected to be not implemented |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bunch of commented out code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea of these heavily commented-out tests is that lambda.move is the original test, with no comments. Some errors don't show up, so we comment out the code generating errors on lambda.move, and call that lambda2.move. That test shows certain other errors, so we comment out the relevant lines there, giving lambda3.move, etc. I left the commented-out lines to keep the line numbers the same. Since there is an empty line, I'll add a comment on that line to indicate what we are doing.
This issue is stale because it has been open 45 days with no activity. Remove the |
Description
Catch all errors in
move-compiler-v2/tests/checking/typing/lambda.move
in Compiler V2,after splitting and gradually commenting out code as
lambda[2-5].move
,to avoid shadowing by other errors. Lay groundwork for support of lambdas in various capacities.
Fixes #14633.
function_checker
internal_error
toerror
inbytecode_generator
andmodule_generator
to properly show "error" rather than "bug" if lambdas are mistakenly used as values today.
LAMBDA_PARAMS
,LAMBDA_RESULTS
to allow lambdas as general function params or resultsLAMBDA_FIELDS
- support lambdas in struct fieldsLAMBDA_VALUES
- support lambdas in general-purpose valuesLAMBDA_TYPE_PARAMS
laterresult_type_loc
field to move-model'sFunctionData
(and model-builder'sFunEntry
)to more precisely locate errors in function result types.
GlobalEnv::internal_dump_env
to use function- and struct-specific type contextsso that types are shown with correct type parameter names.
How Has This Been Tested?
Running the usual tests.
Key Areas to Review
Note that a few errors are caught quite late, in
bytecode-generator
,and the order in which we catch errors may be a bit surprising to
users (errors in
exp_builder
come first, then errors caught byfunction_checker
, then (much later)bytecode_generator
.).Actually supporting particular subsets of the "experiments" mentioned
above would be difficult, but it seems useful to have the labels to
help understand just what features are supported by the implementation
as we go.
Type of Change
Which Components or Systems Does This Change Impact?
Checklist