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

cmd/go2go: conversion using type lists #39962

Closed
benjaminjkraft opened this issue Jun 30, 2020 · 7 comments
Closed

cmd/go2go: conversion using type lists #39962

benjaminjkraft opened this issue Jun 30, 2020 · 7 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@benjaminjkraft
Copy link

Consider the following code (playground):

func Convert(type T interface{}, U interface{ type T })(t T) U {
	return U(t)
}

It does not compile, with the error:

prog.go2:4:11: cannot convert t (variable of type T) to U

It seems to me like this should compile: the design says

More precisely, the underlying type of the type argument must be identical to the underlying type of one of the types in the type list.

which I understand to mean the underlying type of U must be identical to the underlying type of T; the spec gives that as a sufficient condition to allow U(t).

@benjaminjkraft
Copy link
Author

Relatedly, it looks like the following more specialized function gives the same error:

func ConvertToString(type T interface{ type string })(t T) string {
	return string(t)
}

@ianlancetaylor
Copy link
Contributor

CC @griesemer

I think that strictly speaking the design draft says that this code should not compile. It's an interesting case, though.

@ianlancetaylor ianlancetaylor added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jul 1, 2020
@ianlancetaylor ianlancetaylor added this to the Unreleased milestone Jul 1, 2020
@ianlancetaylor
Copy link
Contributor

The reason I say that it maybe should not compile is that your argument hinges on the underlying type of T, which is a little murky.

@benjaminjkraft
Copy link
Author

I think both design draft and spec refer to underlying types on both sides in the relevant contexts?

Not that I would be particularly sad if it didn't, as long as it's clear: this code didn't end up being very useful to me for other reasons.

@tdakkota
Copy link

tdakkota commented Jul 1, 2020

First case is similar a bit to #39930 (comment).
operand.assignableTo function just fails to match two types.
It happens because there are not checks for underlying

  • *types.TypeParam and *types.top

Second example fails here

if check.identical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) {

Underlying types are identical, but both are Named.

@griesemer
Copy link
Contributor

@tdakkota That may be the reason for this failure but not the reasoning as to why it shouldn't fail.

@ianlancetaylor has pointed at the culprit: The outcome hinges on what the underlying type of a type parameter is. One answer is that it is described by the type list in its constraint. Another one is that the underlying type of a type parameter is itself. Currently we implement the latter. The correct answer may be some variation of the former. This is under active investigation.

@griesemer griesemer self-assigned this Jul 1, 2020
@griesemer
Copy link
Contributor

The first example here is not valid code with Go 1.18. The second example (adjusted) works now as expected. Closing.

@golang golang locked and limited conversation to collaborators Jun 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants