Skip to content
This repository has been archived by the owner on Jun 15, 2023. It is now read-only.

Fix several printing issues with async including an infinite loop. #680

Merged
merged 6 commits into from
Oct 15, 2022

Conversation

cristianoc
Copy link
Contributor

See #679

@cristianoc
Copy link
Contributor Author

The same code paths relevant for this also have an infinite loop: #681

The infinite loop happens when the expression is returned unchanged.
Now checking that some progress is made.
Fixes #681
@cristianoc cristianoc requested a review from mununki October 14, 2022 14:51
@cristianoc cristianoc changed the title More async examples. Fix several printing issues with async including an infinite loop. Oct 14, 2022
@mununki
Copy link
Member

mununki commented Oct 14, 2022

The pattern matching inside funExpr function seems complicated and presumably the Pexp_fun with labeled arg can have attributes, not with Nolabel arg. Is it syntax that only Pexp-fun with Labeled and Optional arg can have attributes?

@cristianoc
Copy link
Contributor Author

Just trying to respect what seem to be the existing conventions. And yes it looks complicated. The attributes I think can be used in JSX to specify @as for arguments right?

@mununki
Copy link
Member

mununki commented Oct 15, 2022

Just trying to respect what seem to be the existing conventions. And yes it looks complicated. The attributes I think can be used in JSX to specify @as for arguments right?

In user space? Not that I know. The attribute for arg is mainly used in Pstr_primitives, I mean the external. We use the attributes such as @as often when we bind to components or functions. The attribute for Pexp_fun is not used as long as I know.
But I see that the output of JSX V3 has @warning attributes for arg.

@mununki
Copy link
Member

mununki commented Oct 15, 2022

In order to make the pattern matching more simple, then I look through several cases of attributes with fun args. I found something strange between labeled and nolabel arg.

let f7 = (@attr ~a, @attr ~b) => ()
let f8 = (@attr a, @attr b) => ()
// (f7) @attr ~a
// @attr is parsed to pexp_attributes
        expression (tests/printer/expr/fun2.res[9,244+9]..[9,244+35])
          attribute "attr" (tests/printer/expr/fun2.res[9,244+10]..[9,244+15])
            []
          Pexp_fun
          Labelled "a"
          None
          pattern (tests/printer/expr/fun2.res[9,244+10]..[9,244+18])
            attribute "ns.namedArgLoc" (tests/printer/expr/fun2.res[9,244+17]..[9,244+18])
              []
            Ppat_var "a" (tests/printer/expr/fun2.res[9,244+10]..[9,244+18])

// (f8) @attr a
// @attr is pared to ppat_attributes
        expression (tests/printer/expr/fun2.res[10,280+9]..[10,280+33])
          Pexp_fun
          Nolabel
          None
          pattern (tests/printer/expr/fun2.res[10,280+16]..[10,280+17])
            attribute "attr" (tests/printer/expr/fun2.res[10,280+10]..[10,280+15])
              []
            Ppat_var "a" (tests/printer/expr/fun2.res[10,280+16]..[10,280+17])

Can we parse the attributes for arg to the ppat_attributes of arg for both cases? The only bs and res.async attributes are parsed to pexp_attributes in Pexp_fun. Then, we may be able to make the more simple implementation of the printer.

@cristianoc
Copy link
Contributor Author

cristianoc commented Oct 15, 2022

The one thing I'm really not sure about is why labelled and unlabelled args are treated differently.
Wondering whether there's something that might make use of the difference.

Also, this

let f12 = @a (@b x) => 3

formats to

let f12 = @a x => 3

@mununki
Copy link
Member

mununki commented Oct 15, 2022

I think we need to check this decision history.
https://github.com/rescript-lang/syntax/blob/master/src/res_core.ml#L1537:L1542

@cristianoc
Copy link
Contributor Author

In order to make the pattern matching more simple, then I look through several cases of attributes with fun args. I found something strange between labeled and nolabel arg.

let f7 = (@attr ~a, @attr ~b) => ()
let f8 = (@attr a, @attr b) => ()
// (f7) @attr ~a
// @attr is parsed to pexp_attributes
       expression (tests/printer/expr/fun2.res[9,244+9]..[9,244+35])
         attribute "attr" (tests/printer/expr/fun2.res[9,244+10]..[9,244+15])
           []
         Pexp_fun
         Labelled "a"
         None
         pattern (tests/printer/expr/fun2.res[9,244+10]..[9,244+18])
           attribute "ns.namedArgLoc" (tests/printer/expr/fun2.res[9,244+17]..[9,244+18])
             []
           Ppat_var "a" (tests/printer/expr/fun2.res[9,244+10]..[9,244+18])

// (f8) @attr a
// @attr is pared to ppat_attributes
       expression (tests/printer/expr/fun2.res[10,280+9]..[10,280+33])
         Pexp_fun
         Nolabel
         None
         pattern (tests/printer/expr/fun2.res[10,280+16]..[10,280+17])
           attribute "attr" (tests/printer/expr/fun2.res[10,280+10]..[10,280+15])
             []
           Ppat_var "a" (tests/printer/expr/fun2.res[10,280+16]..[10,280+17])

Can we parse the attributes for arg to the ppat_attributes of arg for both cases? The only bs and res.async attributes are parsed to pexp_attributes in Pexp_fun. Then, we may be able to make the more simple implementation of the printer.

Yes this makes sense, and should respect the intent of the original code. Basically attributes outside ( ) would be added to the function, and inside (...) to the pattern.
And async goes to the function, and uncurried (. ...) also go to the function.

Is this ^ what you have in mind?

@mununki
Copy link
Member

mununki commented Oct 15, 2022

Yes this makes sense, and should respect the intent of the original code. Basically attributes outside ( ) would be added to the function, and inside (...) to the pattern. And async goes to the function, and uncurried (. ...) also go to the function.

Is this ^ what you have in mind?

Exactly!
But I'm a little worrying about the reason for the decision to treat differently between labeled arg and nolabed arg. Any side-effect after changing it

@cristianoc
Copy link
Contributor Author

I suspect the distinction was not really intentional, and things just developed this way.
@IwanKaramazow do you remember?

@IwanKaramazow
Copy link
Contributor

The distinction was indeed not really intentional, I guess no ReScript developer ever hit this path.

Basically attributes outside ( ) would be added to the function, and inside (...) to the pattern.
And async goes to the function, and uncurried (. ...) also go to the function.

Exactly! This is also my mental model.

@cristianoc
Copy link
Contributor Author

Proposal, I'll add a few more examples and merge this PR. Will go into 10.1 as it needs to fix async.

Then create an issue about the proper solution discussed here, to go into v11, so there's enough time to figure out if it affects anything.

@cristianoc
Copy link
Contributor Author

@cristianoc cristianoc merged commit 5868f41 into master Oct 15, 2022
@cristianoc cristianoc deleted the async_examples branch October 15, 2022 08:12
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants