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

Fix support for recursive components in JSX V4. #5986

Merged
merged 2 commits into from
Feb 6, 2023

Conversation

cristianoc
Copy link
Collaborator

Fixes #5981

@cristianoc cristianoc requested a review from mununki February 6, 2023 12:42
@cristianoc
Copy link
Collaborator Author

@mununki feel free to take over from here. (compiler 10.1 etc).

@cristianoc cristianoc force-pushed the recursive_component_v4 branch from 1dd7a75 to b4d70de Compare February 6, 2023 12:43
@mununki
Copy link
Member

mununki commented Feb 6, 2023

Oh! Thanks!
I couldn't grab a time to look into issues so far, I'll grab time to fix them soon!

@mununki
Copy link
Member

mununki commented Feb 6, 2023

I found one thing missing. The rec keyword from the make function of component needs to be removed, because the internal fnName is called inside after transformation. It can't pass the type checker with unused rec flag 8ad9e03

What do you think?

@mununki
Copy link
Member

mununki commented Feb 6, 2023

Wondering why the test failed. I ran node scripts/ciTest.js -all on my machine, it passes the test.

@cristianoc
Copy link
Collaborator Author

cristianoc commented Feb 6, 2023

I found one thing missing. The rec keyword from the make function of component needs to be removed, because the internal fnName is called inside after transformation. It can't pass the type checker with unused rec flag 8ad9e03

What do you think?

That is breakage, not a fix.

Consider the test:

module Rec = {
   @react.component
   let rec make = () => {
     mm(({}: props))
   }
   and mm = (x) => make(x)
 }

You can't remove the toplevel rec as make and mm call each other.

There is some little annoyance, already present in V3, that if you only have make calling itself, you get a warning of unused rec. That aspect could be investigated separately, and might require thinking about a different transformation.

@cristianoc cristianoc force-pushed the recursive_component_v4 branch from 8ad9e03 to b4d70de Compare February 6, 2023 18:59
@mununki
Copy link
Member

mununki commented Feb 6, 2023

There is some little annoyance, already present in V3, that if you only have make calling itself, you get a warning of unused rec. That aspect could be investigated separately, and might require thinking about a different transformation.

That is correct. It is not applicable except the example calling make itself.

@cristianoc
Copy link
Collaborator Author

cristianoc commented Feb 6, 2023

There is some little annoyance, already present in V3, that if you only have make calling itself, you get a warning of unused rec. That aspect could be investigated separately, and might require thinking about a different transformation.

That is correct. It is not applicable except the example calling make itself.

Perhaps the warning can be addressed by turning this:

  let rec make = {
     let rec \"make$Internal" = (_: props) => make(({}: props))
     }
     and make = {
       let \"V4$Rec" = props => \"make$Internal"(props)
       \"V4$Rec"
     }
     make
   }
 }

into this (remove rec from make$Internal):

  let rec make = {
     let \"make$Internal" = (_: props) => make(({}: props))
     let make = {
       let \"V4$Rec" = props => \"make$Internal"(props)
       \"V4$Rec"
     }
     make
   }
 }

@mununki
Copy link
Member

mununki commented Feb 6, 2023

Perhaps the warning can be addressed by turning this:

  let rec make = {
     let rec \"make$Internal" = (_: props) => make(({}: props))
     }
     and make = {
       let \"V4$Rec" = props => \"make$Internal"(props)
       \"V4$Rec"
     }
     make
   }
 }

into this (remove rec from make$Internal):

  let rec make = {
     let \"make$Internal" = (_: props) => make(({}: props))
     let make = {
       let \"V4$Rec" = props => \"make$Internal"(props)
       \"V4$Rec"
     }
     make
   }
 }

The unused ref flag is not away in the example from the issue:

module Rec1 = {
  type props = {}

  let rec make = {
    @merlin.focus
    let \"make$Internal" = (_: props) => {
      React.null
    }
    let make = {
      let \"V4$Rec1" = props => \"make$Internal"(props)

      \"V4$Rec1"
    }
    make
  }
}

@mununki
Copy link
Member

mununki commented Feb 6, 2023

Oh, that is correct warning

@cristianoc
Copy link
Collaborator Author

into this (remove rec from make$Internal):

  let rec make = {
     let \"make$Internal" = (_: props) => make(({}: props))
     let make = {
       let \"V4$Rec" = props => \"make$Internal"(props)
       \"V4$Rec"
     }
     make
   }
 }

I think that's the desired transform, which gives a warning only when it is a correct one.

@mununki
Copy link
Member

mununki commented Feb 6, 2023

How does it look? rescript-lang/syntax@92a7736

@cristianoc
Copy link
Collaborator Author

How does it look? rescript-lang/syntax@92a7736

Looking good

@mununki mununki merged commit beebcff into master Feb 6, 2023
@cristianoc cristianoc deleted the recursive_component_v4 branch February 7, 2023 07:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

JSXv4: Recursive component produces infinite loop
2 participants