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

Open
benjaminjkraft opened this issue Jun 30, 2020 · 6 comments
Open

cmd/go2go: conversion using type lists #39962

benjaminjkraft opened this issue Jun 30, 2020 · 6 comments
Assignees
Milestone

Comments

@benjaminjkraft
Copy link

@benjaminjkraft benjaminjkraft commented Jun 30, 2020

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

@benjaminjkraft benjaminjkraft commented Jun 30, 2020

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

@ianlancetaylor ianlancetaylor commented Jul 1, 2020

CC @griesemer

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

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jul 1, 2020

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

@benjaminjkraft benjaminjkraft commented Jul 1, 2020

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 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

@griesemer griesemer commented Jul 1, 2020

@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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.