v icon indicating copy to clipboard operation
v copied to clipboard

sumtype: else branch of `if sumtype !is Variant` should consider `sumtype` as `Variant`

Open Hunam6 opened this issue 3 years ago • 4 comments

OS: macos, macOS, 12.1, 21C52
Processor: 8 cpus, 64bit, little endian, Apple M1
CC version: Apple clang version 13.0.0 (clang-1300.0.29.30)

getwd: /Users/hunam/Documents/dev/go2v
vmodules: /Users/hunam/.vmodules
vroot: /Applications/v
vexe: /Applications/v/v
vexe mtime: 2022-02-23 17:36:00
is vroot writable: true
is vmodules writable: true
V full version: V 0.2.4 36c9ed6.9662b79

Git version: git version 2.32.0 (Apple Git-132)
Git vroot status: weekly.2022.07-77-g9662b796
.git/config present: true
thirdparty/tcc status: thirdparty-unknown-unknown de82a130

What did you do?

type Aa = Bb | Cc

struct Bb {
	b int
}

struct Cc {
	c int
}

fn main() {
	aa := Aa(Bb{0})
	if aa !is Bb {
		println('not Bb')
	} else {
		println(aa.b) // should work
	}
}

What did you expect to see?

0

What did you see instead?

report.v:16:14: error: field `b` does not exist or have the same type in all sumtype variants
   14 |         println('not Bb')
   15 |     } else {
   16 |         println(aa.b)
      |                    ^
   17 |     }
   18 | }

Hunam6 avatar Feb 23 '22 18:02 Hunam6

I'm confused. Shouldn't the logic be as below? aa contains Bb. So should be !is Cc... then show Bb. aa can't be !is Bb, because that what was assigned to it.

type Aa = Bb | Cc

struct Bb {
	b int
}

struct Cc {
	c int
}

fn main() {
	aa := Aa(Bb{0})

	if aa !is Cc {
		println(aa) 
	} 
}
/*
result
 Aa(Bb{
    b: 0
})
*/

Another way to view it.

fn main() {
	mut aa := Aa(Bb{0})
	cc := Cc{1}

	if aa !is Cc {
		println(aa)
	}

	aa = cc
	
	if aa is Cc  {
		println(aa)
	}
}

/*	
Aa(Bb{
    b: 0
})
Aa(Cc{
    c: 1
})
*/

Wajinn avatar Mar 15 '22 14:03 Wajinn

Can you try to explain what you mean in other words? I don't get it.

Also for your examples, if that's appropriate, can you use println(aa.something) inside of if/else statements. That may help me understanding.

Hunam6 avatar Mar 15 '22 16:03 Hunam6

Also what I meant with my issue is that: Inside the body of an if statement where the condition is sumtype is Type1, sumtype is assumed to be of variant Type1. So inside the body of an else statement where the previous if statement's condition was sumtype !is Type1, if sumtype has only two variations, sumtype should be assumed to be of variant Type2.

Hunam6 avatar Mar 15 '22 16:03 Hunam6

I interpreted that the intention is for sumtype to allow the usage of several types and to distinguish between the types used versus to be used in place of the struct. If we want the values contained in the struct, then use it directly. Of course the collaborators/developers could be more definite, versus my interpretation.

type Aa = Bb | Cc

struct Bb {
	mut:
	b string = 'hot'
}

struct Cc {
	c int
}

fn main() {
	mut aa := Bb{}
	ee := Cc{18}
	println(aa.b) 
	aa = pass_thru(aa)
	println(aa)
	aa = pass_thru(ee)
	println(aa)
}

// thing parameter takes struct of either Bb or Cc
fn pass_thru(thing Aa) Bb {
	mut xx := Bb{}
	if thing is Bb {
		xx.b = 'good'
	}
	if thing is Cc {
		xx.b = 'bad'
	}
	return xx
}

Wajinn avatar Mar 16 '22 07:03 Wajinn