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

Context function with wildcard generates nonsensical tasty with TYPEBOUNDS as the info a ValDef #18649

Closed
sjrd opened this issue Oct 4, 2023 · 0 comments · Fixed by #18651
Closed

Comments

@sjrd
Copy link
Member

sjrd commented Oct 4, 2023

Compiler version

3.3.1

Minimized code

package simple_trees

class Function {
  def contextFunctionWildcard: ? ?=> String = ???
}

Output

Decoded TASTy Trees:

     0: PACKAGE(118)
     2:   TERMREFpkg 1 [simple_trees]
     4:   TYPEDEF(114) 2 [Function]
     7:     TEMPLATE(93)
     9:       APPLY(10)
    11:         SELECTin(8) 9 [<init>[Signed Signature(List(),java.lang.Object) @<init>]]
    14:           NEW
    15:             TYPEREF 7 [Object]
    17:               TERMREFpkg 6 [java[Qualified . lang]]
    19:           SHAREDtype 15
    21:       DEFDEF(7) 3 [<init>]
    24:         EMPTYCLAUSE
    25:         TYPEREF 10 [Unit]
    27:           TERMREFpkg 11 [scala]
    29:         STABLE
    30:       DEFDEF(70) 12 [contextFunctionWildcard]
    33:         APPLIEDtpt(22)
    35:           TYPEREF 13 [ContextFunction1]
    37:             SHAREDtype 27
    39:           TYPEBOUNDStpt(8)
    41:             TYPEREF 14 [Nothing]
    43:               SHAREDtype 27
    45:             TYPEREF 15 [Any]
    47:               SHAREDtype 27
    49:           IDENTtpt 16 [String]
    51:             TYPEREF 16 [String]
    53:               TERMREF 17 [Predef]
    55:                 SHAREDtype 27
    57:         BLOCK(25)
    59:           LAMBDA(2)
    61:             TERMREFdirect 63
    63:           DEFDEF(19) 18 [$anonfun]
    66:             PARAM(8) 20 [[Unique evidence$ 1]]
    69:               TYPEBOUNDS(4)
    71:                 SHAREDtype 41
    73:                 SHAREDtype 45
    75:               GIVEN
    76:             SHAREDtype 51
    78:             TERMREF 21 [???]
    80:               SHAREDtype 53
    82:             SYNTHETIC
    83:             ARTIFACT
    84:         ANNOTATION(16)
    86:           TYPEREF 22 [ContextResultCount]
    88:             TERMREFpkg 26 [scala[Qualified . annotation][Qualified . internal]]
    90:           APPLY(10)
    92:             SELECTin(6) 30 [<init>[Signed Signature(List(scala.Int),scala.annotation.internal.ContextResultCount) @<init>]]
    95:               NEW
    96:                 SHAREDtype 86
    98:               SHAREDtype 86
   100:             INTconst 1
   102:     ANNOTATION(16)
   104:       TYPEREF 31 [SourceFile]
   106:         SHAREDtype 88
   108:       APPLY(10)
   110:         SELECTin(6) 34 [<init>[Signed Signature(List(java.lang.String),scala.annotation.internal.SourceFile) @<init>]]
   113:           NEW
   114:             SHAREDtype 104
   116:           SHAREDtype 104
   118:         STRINGconst 35 [test-sources/src/main/scala/simple_trees/Function.scala]
   120:

Note in particular the DEFDEF starting at address 63:

    63:           DEFDEF(19) 18 [$anonfun]
    66:             PARAM(8) 20 [[Unique evidence$ 1]]
    69:               TYPEBOUNDS(4)
    71:                 SHAREDtype 41
    73:                 SHAREDtype 45
    75:               GIVEN
    76:             SHAREDtype 51
    78:             TERMREF 21 [???]
    80:               SHAREDtype 53
    82:             SYNTHETIC
    83:             ARTIFACT

The PARAM at address 66 with name evidence$1 has a TYPEBOUNDS as its info. This makes no sense: term symbols cannot have a TYPEBOUNDS as their info.

Alternative view: with -Xprint:typer, we get:

    def contextFunctionWildcard: (?) ?=> String =
      {
        def $anonfun(using evidence$1: ): String = ???
        closure($anonfun)
      }

which also shows that the evidence$1 has an "empty" type. It's actually how the type printer "prints" a TypeBounds of >: Nothing <: Any.

Expectation

The type should be Nothing instead, or in general, the lower bound of the wildcard.

@sjrd sjrd added itype:bug area:typer stat:needs triage Every issue needs to have an "area" and "itype" label labels Oct 4, 2023
sjrd added a commit to dotty-staging/dotty that referenced this issue Oct 5, 2023
…ext function.

Since the param types come from type arguments to
`ContextFunctionN[...]`, nothing prevents them a priori from being
wildcard type params, i.e., `TypeBounds`. However, that is not a
valid type to give to a concrete term param.

We can arbitrarily choose any type that conforms to the bounds,
which realistically means one of the two bounds. Since type
inference already chooses the lower bound when explicitly writing
the context function, we align and choose the lower bound when
materializing it.
@sjrd sjrd self-assigned this Oct 5, 2023
@sjrd sjrd removed the stat:needs triage Every issue needs to have an "area" and "itype" label label Oct 5, 2023
sjrd added a commit to dotty-staging/dotty that referenced this issue Oct 12, 2023
…ext function.

Since the param types come from type arguments to
`ContextFunctionN[...]`, nothing prevents them a priori from being
wildcard type params, i.e., `TypeBounds`. However, that is not a
valid type to give to a concrete term param.

We can arbitrarily choose any type that conforms to the bounds,
which realistically means one of the two bounds. Since type
inference already chooses the lower bound when explicitly writing
the context function, we align and choose the lower bound when
materializing it.
sjrd added a commit that referenced this issue Oct 12, 2023
…unction. (#18651)

Since the param types come from type arguments to
`ContextFunctionN[...]`, nothing prevents them a priori from being
wildcard type params, i.e., `TypeBounds`. However, that is not a valid
type to give to a concrete term param.

We can arbitrarily choose any type that conforms to the bounds, which
realistically means one of the two bounds. Since type inference already
chooses the lower bound when explicitly writing the context function, we
align and choose the lower bound when materializing it.
WojciechMazur pushed a commit that referenced this issue Jun 19, 2024
…unction.

Since the param types come from type arguments to
`ContextFunctionN[...]`, nothing prevents them a priori from being
wildcard type params, i.e., `TypeBounds`. However, that is not a
valid type to give to a concrete term param.

We can arbitrarily choose any type that conforms to the bounds,
which realistically means one of the two bounds. Since type
inference already chooses the lower bound when explicitly writing
the context function, we align and choose the lower bound when
materializing it.

[Cherry-picked 242e68f]
WojciechMazur added a commit that referenced this issue Jun 20, 2024
… context function." to LTS (#20645)

Backports #18651 to the LTS branch.

PR submitted by the release tooling.
[skip ci]
WojciechMazur pushed a commit that referenced this issue Jun 20, 2024
…unction.

Since the param types come from type arguments to
`ContextFunctionN[...]`, nothing prevents them a priori from being
wildcard type params, i.e., `TypeBounds`. However, that is not a
valid type to give to a concrete term param.

We can arbitrarily choose any type that conforms to the bounds,
which realistically means one of the two bounds. Since type
inference already chooses the lower bound when explicitly writing
the context function, we align and choose the lower bound when
materializing it.

[Cherry-picked 242e68f]
WojciechMazur added a commit that referenced this issue Jun 20, 2024
… context function." to LTS (#20698)

Backports #18651 to the LTS branch.

PR submitted by the release tooling.
[skip ci]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant