Skip to content

Cannot implement empty interface with different interface #24193

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

Open
einar-hjortdal opened this issue Apr 12, 2025 · 7 comments
Open

Cannot implement empty interface with different interface #24193

einar-hjortdal opened this issue Apr 12, 2025 · 7 comments
Labels
Bug This tag is applied to issues which reports bugs. Unit: Checker Bugs/feature requests, that are related to the type checker.

Comments

@einar-hjortdal
Copy link
Contributor

einar-hjortdal commented Apr 12, 2025

Describe the bug

An empty interface is a contract that matches all types, therefore any type implements an empty interface.

Reproduction Steps

module main

interface EverythingImplementsThis {}

fn throw_error() ! {
	return error('bro')
}

fn main() {
	mut res := map[int]EverythingImplementsThis{}
	for i := 0; i < 10; i++ {
		throw_error() or { res[i] = err } // error: cannot implement interface `EverythingImplementsThis` with a different interface `IError`
	}
}

Expected Behavior

Correctly assign Error struct implementing IError to a EverythingImplementsThis

Current Behavior

Thrown error

Possible Solution

No response

Additional Information/Context

No response

V version

V 0.4.10 c2e27ef

Environment details (OS name and version, etc.)

|V full version      |V 0.4.10 537605a.c2e27ef
|:-------------------|:-------------------
|OS                  |linux, "openmamba release 2024.6 for x86_64 (rolling)"
|Processor           |8 cpus, 64bit, little endian, Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
|Memory              |0.41GB/31.16GB
|                    |
|V executable        |/home/einar/.local/lib64/v/v
|V last modified time|2025-04-12 07:08:24
|                    |
|V home dir          |OK, value: /home/einar/.local/lib64/v
|VMODULES            |OK, value: /home/einar/.vmodules
|VTMP                |OK, value: /tmp/v_1000
|Current working dir |OK, value: /home/einar/Documents/projects/vlang/active/redict
|                    |
|Git version         |git version 2.49.0
|V git status        |weekly.2025.14-35-gc2e27ef2
|.git/config present |true
|                    |
|cc version          |cc (GCC) 14.2.1 20240909
|gcc version         |gcc (GCC) 14.2.1 20240909
|clang version       |N/A
|tcc version         |tcc version 0.9.28rc 2024-07-31 HEAD@1cee0908 (x86_64 Linux)
|tcc git status      |thirdparty-linux-amd64 0134e9b9
|emcc version        |N/A
|glibc version       |ldd (GNU libc) 2.41

Note

You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote.
Other reactions and those to comments will not be taken into account.

@einar-hjortdal einar-hjortdal added the Bug This tag is applied to issues which reports bugs. label Apr 12, 2025
einar-hjortdal pushed a commit to einar-hjortdal/redict that referenced this issue Apr 12, 2025

Unverified

No user is associated with the committer email.
@einar-hjortdal
Copy link
Contributor Author

This workaround seems to work but I do not believe this is right

throw_error() or { res[i] = err as EverythingImplementsThis }

@felipensp felipensp added the Unit: Checker Bugs/feature requests, that are related to the type checker. label Apr 12, 2025
@jorgeluismireles
Copy link

I remember @spytheman said errors are not for storing in maps nor arrays but for dispatched. #23360

@einar-hjortdal
Copy link
Contributor Author

einar-hjortdal commented Apr 15, 2025

I remember @spytheman said errors are not for storing in maps nor arrays but for dispatched. #23360

Sometimes errors are expected to happen:
In this function a map is created with values retrieved by a service, this service may return valid key/value pairs but also errors for some keys. These errors have to be given to the user to let the user handle them. The service connector should not handle these errors for the user.

In any case: all types implement the empty interface, as it is a contract with no requirements. IError satisfies the requirements of an empty interface, and therefore it implements it.

@jorgeluismireles
Copy link

We can't store results like ! but we can store options like ?string, so we can transform a result into an option, and then check for errors checking for options other than none:

import net.http

struct Response {
	site  string
	bytes int
	error ?string
}

fn main() {
	mut resps := []Response{}
	for site in [ 'google.com', 'good-nice-cheap.com' ] {
		a := http.get('http://${site}') or {
			resps << Response{ site:site, error:'${err}' }
			continue
		}
		resps << Response{ site:site, bytes:a.body.len }
	}
	println('${resps}')
}
jorge@jorge-H81H3-M4:~/bugs$ v run 24226.v
[Response{
    site: 'google.com'
    bytes: 17033
    error: Option(none)
}, Response{
    site: 'good-nice-cheap.com'
    bytes: 0
    error: Option('net: socket error: -2; could not resolve address good-nice-cheap.com:80 in dial_tcp')
}]

@einar-hjortdal
Copy link
Contributor Author

einar-hjortdal commented Apr 16, 2025

We can't store results like ! but we can store options like ?string, so we can transform a result into an option, and then check for errors checking for options other than none:

Your example works well as an example, but it is naive to suggest this approach can be used in all situations. In my situation your approach requires me to wrap all types with a struct that contains an error field and this just causes a mess:

// currently
interface Value = {}

// now I would have to wrap Value with another struct
struct ValueWrapper {
  actual_value Value
  error string
}

Now the user always gets a struct for each and everything, and needs to access it as a property of ValueWrapper every time, and check if the property error is a string that isn't '' (what even is the point of using an option type at this point?) on top of already having to match the type of Value.

The user already has to match the type of Value, adding a Error case is much simpler.

Though, I could create my own Error struct and give it the same message, but why would I need to do that when the error is already there?

@jorgeluismireles
Copy link

A really good thing V's interfaces define are not only methods but fields:

interface Value {
	error ?string
}

struct Response {
	site  string
	bytes int
	error ?string
}

fn main() {
	mut resps := []Value{}
...
			resps << Response{ site:site, error:'${err}' }
...

@einar-hjortdal
Copy link
Contributor Author

I think you're ignoring what I am saying

einar-hjortdal pushed a commit to einar-hjortdal/redict that referenced this issue Apr 23, 2025

Unverified

No user is associated with the committer email.
… the new struct Nil and returned as Value, as specified by the RESP protocol

Squashed commit of the following:

commit f335b7d
Author: Einar Hjortdal <einar-hjortdal@outlook.com>
Date:   Wed Apr 23 11:13:41 2025 +0200

    Increment version

commit d55849c
Author: Einar Hjortdal <einar-hjortdal@outlook.com>
Date:   Wed Apr 23 11:08:27 2025 +0200

    Fix up hset and tests

commit b8632ea
Author: Einar Hjortdal <einar-hjortdal@outlook.com>
Date:   Wed Apr 23 09:52:10 2025 +0200

    Minor changes

commit 5f2f735
Author: Einar Hjortdal <einar-hjortdal@outlook.com>
Date:   Thu Apr 17 10:22:28 2025 +0200

    Cleanup ProtoNil

commit 88c469a
Author: Einar Hjortdal <einar-hjortdal@outlook.com>
Date:   Sat Apr 12 11:36:00 2025 +0200

    fix read_map

commit 3edf3b7
Author: Einar Hjortdal <einar-hjortdal@outlook.com>
Date:   Sat Apr 12 11:11:28 2025 +0200

    Rewrite tests

commit f4e3f5c
Author: Einar Hjortdal <einar-hjortdal@outlook.com>
Date:   Sat Apr 12 10:20:31 2025 +0200

    Apparently Error does not implement an empty interface vlang/v#24193

commit f673a47
Author: Einar Hjortdal <einar-hjortdal@outlook.com>
Date:   Fri Apr 11 17:33:17 2025 +0200

    cgen error caused by option type, giving up

commit 89cd633
Author: Einar Hjortdal <einar-hjortdal@outlook.com>
Date:   Fri Apr 11 17:19:41 2025 +0200

    Fix option type issue

commit e0946ae
Author: Einar Hjortdal <einar-hjortdal@outlook.com>
Date:   Fri Apr 11 16:56:14 2025 +0200

    Close to finish

commit ddc4955
Author: Einar Hjortdal <einar-hjortdal@outlook.com>
Date:   Fri Apr 11 11:15:00 2025 +0200

    Nil implements IError

commit 1e49b0f
Author: Einar Hjortdal <einar-hjortdal@outlook.com>
Date:   Fri Apr 11 10:54:20 2025 +0200

    Remove comment separators

commit 570761a
Author: Einar Hjortdal <einar-hjortdal@outlook.com>
Date:   Fri Apr 11 10:47:10 2025 +0200

    Implement Value and Nil

commit a225148
Author: Einar Hjortdal <einar-hjortdal@outlook.com>
Date:   Fri Apr 11 10:32:11 2025 +0200

    Remove submodules
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug This tag is applied to issues which reports bugs. Unit: Checker Bugs/feature requests, that are related to the type checker.
Projects
None yet
Development

No branches or pull requests

3 participants