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

Idempotence bug involving moving comments #340

Closed
mrkkrp opened this issue Aug 28, 2019 · 4 comments · Fixed by #577
Closed

Idempotence bug involving moving comments #340

mrkkrp opened this issue Aug 28, 2019 · 4 comments · Fixed by #577
Assignees
Labels
bug Something isn't working comments Issues related to comment placement idempotence Idempotence issues and solutions.

Comments

@mrkkrp
Copy link
Member

mrkkrp commented Aug 28, 2019

From formatting parsec3:

Original input:

mergeErrorReply :: ParseError -> Reply s u a -> Reply s u a
mergeErrorReply err1 reply -- XXX where to put it?
    = case reply of
        Ok x state err2 -> Ok x state (mergeError err1 err2)
        Error err2      -> Error (mergeError err1 err2)

1 pass:

mergeErrorReply :: ParseError -> Reply s u a -> Reply s u a
mergeErrorReply err1 reply = -- XXX where to put it?
  case reply of
    Ok x state err2 -> Ok x state (mergeError err1 err2)
    Error err2 -> Error (mergeError err1 err2)

2 pass (fixpoint):

mergeErrorReply :: ParseError -> Reply s u a -> Reply s u a
mergeErrorReply err1 reply =
  -- XXX where to put it?
  case reply of
    Ok x state err2 -> Ok x state (mergeError err1 err2)
    Error err2 -> Error (mergeError err1 err2)
@mrkkrp mrkkrp added bug Something isn't working idempotence Idempotence issues and solutions. labels Aug 28, 2019
@mrkkrp mrkkrp added this to TODO in 0.0.2.0 Aug 28, 2019
@mrkkrp
Copy link
Member Author

mrkkrp commented Sep 2, 2019

This is actually pretty strange. My mental model is that in all cases the comment should be attached to reply and so it always should stay on the same line.

@utdemir
Copy link
Contributor

utdemir commented Sep 11, 2019

Here is a smaller version:

foo reply -- XXX
  = foo

What happens is that when we are deciding whether a comment follows an element, one of the predicates we use is noEltBetween, which checks if the comment follows an element by checking whether the next element starts after the end of the comment. However, in this example, the next element is = foo, and after the first pass we move the = before the comment, so the predicate fails to attach the comment to the same element on the next run.

Similar issues also occur on almost everywhere we move something to a line above. Some examples I made up:

foo = \case
  True -- foo
    -> False
  False -> True
foo
  :: () -- bar
  = foo
a = b $ -- foo
  do
  foo
foo =
  let a -- foo
        = b
   in c

Everything above has idempotence issues.

I couldn't figure out an easy solution. Only thing I can come up with is adding a flag to the located combinator to only conditonally enable comments on some constructs.

@mrkkrp
Copy link
Member Author

mrkkrp commented Sep 12, 2019

However, in this example, the next element is = foo, and after the first pass we move the = before the comment, so the predicate fails to attach the comment to the same element on the next run.

I do not understand is why = between those things would prevent attaching of the comment. I think = by itself is not in the AST and so it should not be in the "span stream" (it could be if we injected things from annotations there, but we currently do not do this).

One thing seems to be clear: while the current approach works decently in most cases, there are many marginal situations where it fails and from what I've seen and investigated, the idempotence issues we're facing right now are not at all easy to fix. Perhaps a completely different approach to comment rendering is necessary here.

@mrkkrp
Copy link
Member Author

mrkkrp commented Sep 12, 2019

OK, more precisely it is not = per se is between the element and the comment, it's the entire match of the match group starting from the equal sign. The comment happens to be inside the match, but it starts after the span of the match, and this condition returns False:

realSrcSpanStart nspn >= realSrcSpanEnd l

We cannot return True when for example the next element happens to enclose the comment because then other things break.

At least it's clear now what exactly is going on here.

@mrkkrp mrkkrp removed this from TODO in 0.0.2.0 Dec 3, 2019
@mrkkrp mrkkrp added this to Harder in Google engagement Apr 9, 2020
@mrkkrp mrkkrp moved this from Harder to Backlog in Google engagement Apr 9, 2020
@mrkkrp mrkkrp added the comments Issues related to comment placement label Apr 9, 2020
@mrkkrp mrkkrp moved this from Backlog to In progress in Google engagement May 5, 2020
@mrkkrp mrkkrp moved this from In progress to Done in Google engagement May 6, 2020
@mrkkrp mrkkrp self-assigned this May 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working comments Issues related to comment placement idempotence Idempotence issues and solutions.
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

2 participants