Skip to content
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

Embed errors in the AST instead of raising #12

Closed
wants to merge 17 commits into from
Closed

Embed errors in the AST instead of raising #12

wants to merge 17 commits into from

Conversation

Burnleydev1
Copy link

Closes #10

Hello @panglesd, I'm sorry, I messed up the previous pr and my changes were no longer reflected there when I pushed.

@Burnleydev1
Copy link
Author

Burnleydev1 commented Mar 27, 2023

I converted the function let check_at_least_one_record ~loc rec_flag tds to return the result type but the sites where this function was called below still gave me errors such as,

loc:location ->
rec_flag ->
type_declaration list ->
(unit, Ppxlib.Location.Error.t) result
This expression has type (unit, Ppxlib.Location.Error.t) result
but an expression was expected of type unit
because it is in the left-hand side of a sequence

and the | Ok selection -> on line 543 gave the error
Error (warning 27): unused variable selection.

@Burnleydev1
Copy link
Author

This method did not work on check_no_collision as I got this error:
This expression has type Ppxlib.Location.Error.t but an expression was expected of type unit because it is in the result of a conditional with no else branch
this was the code with the changes

    List.iter lbls ~f:(fun { pld_name; pld_loc; _ } ->
      if List.mem generated_funs pld_name.txt ~equal:String.equal
      then
        Error (Location.Error.createf
          ~loc:pld_loc
          "ppx_fields_conv: field name %S conflicts with one of the generated functions"
          pld_name.txt))

@Burnleydev1
Copy link
Author

I went through the resources you sent but I am stumped on the application in some functions and where to use a certain method instead of the other.

@panglesd
Copy link

Hello @Burnleydev1!

This is already a good start. Let me give some hints/remarks:

  • check_at_least_one_record currently checks whether there is no nonrec keyword in the type definitions, and that there is at least one record in the type definitions. So, it could be nice to have to return a list of errors, rather than a (unit, error) result which can only contain one error.
  • You have changed the return type of check_at_least_one_record. Before, it was unit, so you could do things such as:
(* has side effects (can raise), but returns unit *)
check_at_least_one_record ...;
(* if we reach this line, there is at least one record *)
rest_of_the_function

However, once check_at_least_one_record is not unit, it (rightfully) becomes an error: the ; separator is used to separate two expression, the first one being of type unit (there is this in the reference manual of OCaml about ; separators): otherwise, what would happen with the return value of the first expression?

So, at the call sites of check_at_least_one_record, you should make sure you handle the return value: maybe, depending on whether it is Ok or Error (or whether the length of the list if it returns a list), you will do different things.


Similarly, look at the type of List.iter, it is: 'a list -> ~f:('a -> unit) -> unit. So, it only performs operations which have side effects (they return unit, so they can only return one value (), so they can only do side effects). You cannot use List.iter any more, since there is now a return value!
You should look for other function on list, which are common on functional programming. For instance List.map, List.filter_map, List.fold_left, ... are functions that are very common and useful in OCaml. Using them, you will be able to gather the list of errors that are found when traversing the list of labels.

@Burnleydev1
Copy link
Author

Thanks @panglesd for the remarks/tips, I will hop on this.

@Burnleydev1
Copy link
Author

Similarly, look at the type of List.iter, it is: 'a list -> ~f:('a -> unit) -> unit. So, it only performs operations which have side effects (they return unit, so they can only return one value (), so they can only do side effects). You cannot use List.iter any more, since there is now a return value!
You should look for other function on list, which are common on functional programming. For instance List.map, List.filter_map, List.fold_left, ... are functions that are very common and useful in OCaml. Using them, you will be able to gather the list of errors that are found when traversing the list of labels.

For this, I used List.filter_map and it worked, I"m trying to fix the errors on the call sites.

@Burnleydev1 Burnleydev1 changed the title Changed check_at_least_one_record to return the result type... Embed errors in the AST instead of raising Mar 29, 2023
@github-iron github-iron added the forwarded-to-js-devs This report has been forwarded to Jane Street's internal review system. label Mar 31, 2023
@Burnleydev1
Copy link
Author

Hi @panglesd, this is an attempt to fix the call site for check_no_collision

Burnleydev1 and others added 17 commits June 8, 2023 18:12
Signed-off-by: Burnleydev1 <[email protected]>
Signed-off-by: Burnleydev1 <[email protected]>
Signed-off-by: Burnleydev1 <[email protected]>
Signed-off-by: Burnleydev1 <[email protected]>
Signed-off-by: Burnleydev1 <[email protected]>
This reverts commit 3cbb971.

Signed-off-by: Burnleydev1 <[email protected]>
Signed-off-by: Burnleydev1 <[email protected]>
Signed-off-by: Burnleydev1 <[email protected]>
@Burnleydev1 Burnleydev1 deleted the error_embed branch June 11, 2023 08:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
forwarded-to-js-devs This report has been forwarded to Jane Street's internal review system.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Embed errors in the AST instead of raising
4 participants