Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Rewrite right-associative rewrite#7741

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
som-snytt wants to merge5 commits intoscala:2.13.x
base:2.13.x
Choose a base branch
Loading
fromsom-snytt:issue/5073-rassoc-method-value

Conversation

som-snytt
Copy link
Contributor

@som-snyttsom-snytt commentedFeb 12, 2019
edited
Loading

Defer any rewriting from parser to typedApply.

The application is typechecked in the normal way
and evaluation order rejiggered after. In particular,
there is no need to re-typecheck after re-inlining,
for more precise types.

Original intention was to piggyback onthe fix for 1980 by inlining a bit more, but typing is largely done by the time the rewrite is rewritten. This is retronym's suggested follow-up, perhaps.

Fixesscala/bug#4518
Fixesscala/bug#5073
Fixesscala/bug#10693
Fixesscala/bug#11117

Aggravates bugs 5073 (pos/tcpoly_ticket2096.scala) and maybe 11397 (run/t4225e.scala, which demonstrates 10693).

@som-snytt
Copy link
ContributorAuthor

@lrytz thx for bumping this on the one-year anniversary.

dwijnand reacted with laugh emoji

@lrytz
Copy link
Member

🎈

@lrytz
Copy link
Member

Here's an example that shows the issue with this approach:

classA {def/: (z:A)(op:Int):A=???defself=thisdefbar(x:A,y:A)= (x.self/: y.self)(1)}

intypedApply ofy.self./:(x.self), we build a block

{  final <synthetic> <artifact> val rassoc$1: A = x.self;  y.self./:(rassoc$1)}

Callingtyped(blk) fails because the typer throughtypedBlock, and typing blocks isnotFUN in terms ofmode. So we get

error: missing argument list for method /: in class AUnapplied methods are only converted to functions when a function type is expected.

Just putting the typer inFUNmode wouldn't be enough, as the second param list needs to go into the block.

Names and defaults has the same problem, and does it with a lot of complexity (it builds a block for the inner Apply, then takes it apart for outer Applys and inserts them into the block). Here, it should be possible to avoid this complexity and just build the block at the very end, after type checking the full application (y.self./:(x.self)(1))?

@lrytz
Copy link
Member

A different issue caused by this PR is that we get a lint warning on(1, 2) :: Nil

Test.scala:2: warning: adapted the argument list to the expected 2-tuple: add additional parens instead        signature: List.::[B >: A](elem: B): List[B]  given arguments: 1, 2 after adaptation: List.::((1, 2): (Int, Int))  val x = (1,2) :: Nil                ^

before the parser would spit out

    val x = {      final <synthetic> <artifact> val rassoc$1 = scala.Tuple2(1, 2);      Nil.$colon$colon(rassoc$1)    }

but now it'sval x = Nil.$colon$colon(1, 2).

@som-snytt
Copy link
ContributorAuthor

Thanks@lrytz for the insight. If I wake up later today, I will try to grok it.

I wasn't sure if returning to this PR was worth the communal trouble; should I change the title to "Complexify right-associative rewrite"?

If we had mini-phases, we could have a mini-phase calledp5073 after the ticket. Every ticket could have a test and a custom transform.

There's a similar challenge in the stabilization PR about whether to muck with trees in-flight, though there the effect is artificial rather than actual order of evaluation.

@lrytz
Copy link
Member

lrytz commentedFeb 13, 2020
edited
Loading

worth the communal trouble

I like the the simplification, it seems more tractable

similar challenge in the stabilization PR

Yeah.. I'm looking atscala/bug#11756 tomorrow, I think it would be good to have in 2.13.2, maybe just a minimal fix without changing the strategy.

@som-snyttsom-snytt marked this pull request as draftApril 17, 2020 00:53
@som-snyttsom-snytt reopened thisMay 9, 2020
@SethTisueSethTisue modified the milestones:2.13.3,2.13.4May 12, 2020
@SethTisueSethTisue removed this from the2.13.4 milestoneJul 28, 2020
@som-snyttsom-snytt reopened thisMay 19, 2021
@scala-jenkinsscala-jenkins added this to the2.13.7 milestoneMay 19, 2021
@som-snyttsom-snytt changed the titleSimplify right-associative rewriteSimplify right-associative rewrite [ci: last-only]May 20, 2021
@som-snyttsom-snyttforce-pushed theissue/5073-rassoc-method-value branch from6e754c2 to7d8ebeeCompareMay 20, 2021 04:14
@som-snytt
Copy link
ContributorAuthor

som-snytt commentedMay 20, 2021
edited
Loading

@lrytz A year later, I piggybacked on your fix for stabilization.

Edit: I see the(42, 27) :: Nil idiom is idiomatic, so I will try to mitigate that. I mentioned it on discord.

Appselmode sounds like a Swiss tart made with little apples.

@som-snytt
Copy link
ContributorAuthor

som-snytt commentedMay 20, 2021
edited
Loading

The previous easy tweak worked, but now:

[error] /home/travis/build/scala/scala/src/reflect/scala/reflect/internal/util/package.scala:17:23: Unused import[error] import scala.language.existentials // scala/bug#6541[error]                       ^[error] one error found

I'll try a local bootstrap after all.

...oh I guess it's fatal on CI now. More late pandemic brain fog.

Except for the part where

[error] /home/jenkins/workspace/scala-2.13.x-validate-main/src/reflect/scala/reflect/internal/util/package.scala:46:13: inferred existential type Class[?0] forSome { type ?0 >: _$1; type _$1 }, which cannot be expressed by wildcards, should be enabled[error] by making the implicit value scala.language.existentials visible.[error] ----[error] This can be achieved by adding the import clause 'import scala.language.existentials'[error] or by setting the compiler option -language:existentials.[error] See the Scaladoc for value scala.language.existentials for a discussion[error] why the feature should be explicitly enabled.[error]       clazz.getSuperclass :: clazz.getInterfaces.toList map (c => shortClass(c)) mkString " with "[error]             ^[error] one error found[error] (reflect / Compile / compileIncremental) Compilation failed

Rebroke this:

    def shortClass(clazz: Class[_]): String = {  final <synthetic> <artifact> val rassoc$1: Class[?0] forSome { type ?0 >: _$1; type _$1 } = clazz.getSuperclass();  scala.Predef.wrapRefArray[Class[_]](clazz.getInterfaces()).toList.::[Class[_]](rassoc$1)}.map[String](((c: Class[_]) => C.this.shortClass(c))).mkString(" with ")  }// vs    def shortClass(clazz: Class[_]): String = {      final <synthetic> <artifact> val rassoc$1: Class[?0] = clazz.getSuperclass();      scala.Predef.wrapRefArray[Class[_]](clazz.getInterfaces()).toList.::[Class[_]](rassoc$1).map[String](((c: Class[_]) => C.this.shortClass(c))).mkString(" with ")    }

@som-snyttsom-snyttforce-pushed theissue/5073-rassoc-method-value branch fromeffa62a to8dd8424CompareMay 20, 2021 07:36
@SethTisueSethTisue removed this from the2.13.12 milestoneJun 5, 2023
@som-snyttsom-snytt reopened thisNov 9, 2024
@scala-jenkinsscala-jenkins added this to the2.13.16 milestoneNov 9, 2024
@som-snyttsom-snyttforce-pushed theissue/5073-rassoc-method-value branch 3 times, most recently fromb6afeeb toc646f90CompareNovember 16, 2024 20:13
@som-snytt
Copy link
ContributorAuthor

som-snytt commentedNov 16, 2024
edited
Loading

Reviewing previous comments, I see the initial effort in 2019 neededAPPSELmode; then the follow-up in 2021 prompted lrytz to ask did you even read my PR description, the way a professor might say did you even read the paper that describes this fundamental concept; not sure what I was talking about in 2022-23.

Currently, there are a few old TODO comments I wouldn't mind addressing that are out of scope;

  • not sure the "arg" annotation is needed to detect that a view was applied (replacing the ApplyView with an attachment is one of the TODOs);
  • test that deprecated infix type arg is not broken.
  • The commit could be split into "trivial refactor or picking whitespace nits" and actual changes.
  • 30 LOCtransformRassoc could be moved to an outer scope where it is less distracting to the reader.
  • run/t5073 isrun/1980b.

Tip: You cannot create task list items within closed issues or issues with linked pull requests.

@som-snytt
Copy link
ContributorAuthor

Does anyone get the Merriam-Webster email? Today's word is "steadfast". Their quiz:

Rearrange the letters to form a verb meaning "to make steadfast": ZBIILEAST

@som-snyttsom-snyttforce-pushed theissue/5073-rassoc-method-value branch fromc646f90 to1261ad5CompareNovember 17, 2024 20:05
Parser marks application as right-associative.Typer identifies subexpressions to pre-computein order to preserve left-to-right evaluation.
@som-snyttsom-snyttforce-pushed theissue/5073-rassoc-method-value branch 2 times, most recently from2883426 to92bd67aCompareNovember 17, 2024 23:55
@som-snyttsom-snyttforce-pushed theissue/5073-rassoc-method-value branch fromcb5f090 to15b6afbCompareNovember 18, 2024 08:02
@som-snyttsom-snytt marked this pull request as ready for reviewNovember 18, 2024 09:44
@som-snytt
Copy link
ContributorAuthor

Rebased and followed up on the items. Did not split the first commit. Did remove the two specialApply classes, as handling them specially is error-prone; using attachments is comfortable by now.

def isStab(x: Tree) = x match { case ValDef(_, nm, _, _) => nm.startsWith(nme.STABILIZER_PREFIX) case _ => false }
val (stabs, rassocs) = all.partition(isStab)
context.pendingStabilizers = Nil
Block(rassocs ++ stabs.reverse, expr).setPos(expr.pos).setType(expr.tpe)
Copy link
Member

@lrytzlrytzNov 18, 2024
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

can there be multiple inrassocs? reverse?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

yes, and this is correctly ordered, as I'm sure a test demonstrates.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

👍

def f = hashCode :: toString :: Nil

deff:List[Any]= {final <synthetic> <artifact>valrassoc$2:Int=C.this.hashCode();final <synthetic> <artifact>valrassoc$1:String=C.this.toString();      scala.`package`.Nil.::[String](rassoc$1).::[Any](rassoc$2)    };

Comment on lines 6360 to 6361
case view @ Apply(coercion, coerced :: Nil) if view.hasAttachment[AppliedImplicitView.type] && shouldInsertRassocs =>
treeCopy.Apply(view, coercion, addStabilizers(coerced) :: Nil)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

this piece made me wonder.

so the example is this

class Lobject E extends Lclass C(val h: Int, val t: L) extends Lclass D(val l: () => L) {  def #:: (o: Int): L = new C(o, l())}object T {  implicit def toD(l: => L): D = new D(() => l)}a #:: b #:: E

When the outer implicit conversion is typed (adaptToMember,T.toD(T.toD(E).#::(rassoc$1)))

  • we end up intypedApply as expected. The argumentT.toD(E).#::(rassoc$1) is typed withoutAPPSELmode, that flag is removed intypedArg.
  • but the argument tree is already typed, and importantly,context.pendingStabilizers is already populated withrassoc$1
  • at the beginning ofdef typed
    • shouldInsertStabilizers is true, we save the pending one in a local and setcontext.pendingStabilizers = Nil
    • this means the stabilizer is not added by mistake. the logic around that indef typed doesn't work with trees that are already typed

we can probably fix that instead of the special case here?

som-snytt reacted with eyes emoji
Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

There is no emoji reaction with blurry eyes, but I'll think about it later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'll try turningcontext.pendingStabilizers into a tree attachment.

Copy link
Member

@lrytzlrytzNov 19, 2024
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Added a commit, but it's not replacingcontext.pendingStabilizers unfortunately. Maybe you have a better idea, I added some comments to try to explain what this is about.

@lrytzlrytzforce-pushed theissue/5073-rassoc-method-value branch from5839607 to9240ec7CompareNovember 19, 2024 15:20
@lrytzlrytzforce-pushed theissue/5073-rassoc-method-value branch from9240ec7 to4bb452fCompareNovember 19, 2024 15:34
@lrytz
Copy link
Member

Bug found while trying stuff

object T extends App {  def x = println("x")  def y = println("y")  object Nol {    def ::(x: Any)(implicit o: Ordering[Int]): Nol.type = Nol  }  x :: y :: Nol}

The rassoc transformation is not done (not in your version, and not with my commit on top).

som-snytt reacted with eyes emoji

@som-snytt
Copy link
ContributorAuthor

OK, I'm awake. Thanks for the code comments, which I read, it's useful to have a published paper that explains the theoretical basis.

I see why you didn't like the "special case" (I don't think you liked it two years ago). I'll have a second coffee before applying myself to review.

My first thought was that the new attachment is a different way to pronounce "tomato", but it's probably also a cleaner basis for fixing bugs in the general approach.

@lrytz
Copy link
Member

What would really help: a single test file for everything around stabilizers and rassocs, their combinations, interaction with implicit params and conversions (and other features?).

Scala 3 seems to get it all right, at least the few examples I tried. Can we align with the way it's implemented there? I didn't take a look.

@SethTisueSethTisue modified the milestones:2.13.16,2.13.17Dec 12, 2024
@SethTisueSethTisue marked this pull request as draftFebruary 28, 2025 02:48
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@lrytzlrytzlrytz left review comments

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
2.13.17
5 participants
@som-snytt@lrytz@SethTisue@szeiger@scala-jenkins

[8]ページ先頭

©2009-2025 Movatter.jp