Skip to content

SI-8962 Fix regression with skolems in pattern translation#4094

Merged
retronym merged 1 commit intoscala:2.11.xfrom
retronym:ticket/8962
Nov 6, 2014
Merged

SI-8962 Fix regression with skolems in pattern translation#4094
retronym merged 1 commit intoscala:2.11.xfrom
retronym:ticket/8962

Conversation

@retronym
Copy link
Member

@retronym retronym commented Nov 6, 2014

During the refactoring of error reporting in 258d95c, the result
of Context#reportError was changed once we had switched to
using a ThrowingReporter, which is still the case in post
typer phase typechecking

This was enough to provoke a type error in the enclosed test.
Here's a diff of the typer log:

%  scalac-hash 258d95~1 -Ytyper-debug sandbox/test.scala 2>&1 | tee sandbox/good.log
%  scalac-hash 258d95 -Ytyper-debug sandbox/test.scala 2>&1 | tee sandbox/bad.log
%  diff -U100 sandbox/{good,bad}.log | gist --filename=SI-8962-typer-log.diff
https://gist.github.com/retronym/3ccbe7e0791447d272a6

The test Context#reportError happens to be used when deciding
whether the type checker should be lenient when it hits a type error.
In lenient mode (see adaptMismatchedSkolems), it adapt retries
with after slackening the expected type by replacing GADT and
existential skolems with wildcard types. This is to accomodate
known type-incorrect trees generated by the pattern matcher.

This commit restores the old semantics of reportError, which means
it is false when a ThrowingReporter is being used.

Review by @adriaanm

@scala-jenkins scala-jenkins added this to the 2.11.5 milestone Nov 6, 2014
@retronym
Copy link
Member Author

retronym commented Nov 6, 2014

I did consider refactoring adaptMismatchSkolems to use a more intention revealing method name on Contexts than isReporting. But to be conservative, I think it is important we restore the old behaviour of isReporting anyway, as it has a few other callers.

During the refactoring of error reporting in 258d95c, the result
of `Context#reportError` was changed once we had switched to
using a `ThrowingReporter`, which is still the case in post
typer phase typechecking

This was enough to provoke a type error in the enclosed test.
Here's a diff of the typer log:

    %  scalac-hash 258d95~1 -Ytyper-debug sandbox/test.scala 2>&1 | tee sandbox/good.log
    %  scalac-hash 258d95 -Ytyper-debug sandbox/test.scala 2>&1 | tee sandbox/bad.log
    %  diff -U100 sandbox/{good,bad}.log | gist --filename=SI-8962-typer-log.diff
    https://gist.github.com/retronym/3ccbe7e0791447d272a6

The test `Context#reportError` happens to be used when deciding
whether the type checker should be lenient when it hits a type error.
In lenient mode (see `adaptMismatchedSkolems`), it `adapt` retries
with after slackening the expected type by replacing GADT and
existential skolems with wildcard types. This is to accomodate
known type-incorrect trees generated by the pattern matcher.

This commit restores the old semantics of `reportError`, which means
it is `false` when a `ThrowingReporter` is being used.

For those still reading, here's some more details.

The trees of the `run2` example from the enclosed test. Notice that
after typechecking, `expr` has a type containing GADT skolems. The
pattern matcher assumes that calling the case field accessor `expr`
on the temporary val `x2 : Let[A with A]` containing the scrutinee
will result in a compatible expression, however this it does not.
Perhaps the pattern matcher should generate casts, rather than
relying on the typer to turn a blind eye.

```
[[syntax trees at end of                     typer]] // t8962b.scala
...
    def run2[A](nc: Outer2[A,A]): Outer2[Inner2[A],A] = nc match {
      case (expr: Outer2[Inner2[?A2 with ?A1],?A2 with ?A1])Let2[A with A]((expr @ _{Outer2[Inner2[?A2 with ?A1],?A2 with ?A1]}){Outer2[Inner2[?A2 with ?A1],?A2 with ?A1]}){Let2[A with A]} =>
        (expr{Outer2[Inner2[?A2 with ?A1],?A2 with ?A1]}: Outer2[Inner2[A],A]){Outer2[Inner2[A],A]}
    }{Outer2[Inner2[A],A]}

[[syntax trees at end of                    patmat]] // t8962b.scala

    def run2[A](nc: Outer2[A,A]): Outer2[Inner2[A],A] = {
      case <synthetic> val x1: Outer2[A,A] = nc{Outer2[A,A]};
      case5(){
        if (x1.isInstanceOf[Let2[A with A]])
          {
            <synthetic> val x2: Let2[A with A] = (x1.asInstanceOf[Let2[A with A]]: Let2[A with A]){Let2[A with A]};
            {
              val expr: Outer2[Inner2[?A2 with ?A1],?A2 with ?A1] = x2.expr{<null>};
              matchEnd4{<null>}((expr{Outer2[Inner2[?A2 with ?A1],?A2 with ?A1]}: Outer2[Inner2[A],A]){Outer2[Inner2[A],A]}){<null>}
              ...
```
@retronym retronym changed the title SI-8962 Fix regression silent mode during patmat typechecking SI-8962 Fix regression with skolems in pattern translation Nov 6, 2014
@adriaanm
Copy link
Contributor

adriaanm commented Nov 6, 2014

LGTM!

retronym added a commit that referenced this pull request Nov 6, 2014
SI-8962 Fix regression with skolems in pattern translation
@retronym retronym merged commit 000de44 into scala:2.11.x Nov 6, 2014
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.

3 participants