V: Segment fault with 'mut' Matching sum types

Created on 8 Dec 2020  路  6Comments  路  Source: vlang/v


V version: V 0.1.30 5e59718.bac6be2
OS: Linux version 5.4.72-gentoo (root@plasma) (gcc version 9.3.0 (Gentoo 9.3.0-r1 p3))

What did you do?

struct Dog {}
struct Cat {}

fn (d Dog) speak() { println('woof') }
fn (c Cat) speak() { println('meow') }

type Pet = Dog | Cat

fn (mut p Pet) speak() {
    println('Speak')
    match p {
        Dog { p.speak() }
        Cat { p.speak() }
    }
}

fn main() {
    mut pet := Pet(Cat{})
    pet.speak()
}

What did you expect to see?
No problem in matching types of Pet.speak() with 'mu p' and with 'p' vars

What did you see instead?
Infinite loop with final segment fault!
Work fine when I remove the 'mut' in

fn (mut p Pet) speak() {

Also work if I use (but perhaps fail if the fn has parameters):


fn (mut p Pet) speak() {
    println('Speak')
    match p {
        Dog { (p as Dog).speak() }
        Cat { (p as Cat).speak() }
    }
}
Bug

Most helpful comment

Thanks @joe-conigliaro . After update V it works fine.
Only an advise on the behaviour (as you say unclear). This also work:

struct Dog {}
struct Cat {}

fn (mut d Dog) speak() { println('woof') }
fn (mut c Cat) speak() { println('meow') }

type Pet = Dog | Cat

fn (p Pet) speak() {
    println('Speak')
    match mut p {
        Dog { p.speak() }
        Cat { p.speak() }
    }
}

fn main() {
    mut pet := Pet(Cat{})
    pet.speak()
}

it doesn't make sense that 'fn (p Pet)' is inmutable and then 'match' mark as mutable and send as mutable to Doc/Cat. speak()

All 6 comments

hi @ejtizado I have added a fix so that mut receiver can be used in 44b9ea4 however the match will need to have mut eg:

struct Dog {}
struct Cat {}

fn (d Dog) speak() { println('woof') }
fn (c Cat) speak() { println('meow') }

type Pet = Dog | Cat

fn (mut p Pet) speak() {
    println('Speak')
    match mut p {
        Dog { p.speak() }
        Cat { p.speak() }
    }
}

fn main() {
    mut pet := Pet(Cat{})
    pet.speak()
}

If the receiver/var is mut and the match does not have mut then the smartcast will never occur so you will be calling Pet.speak() in an infinite loop. I'm not sure if we need to handle this any differently in the future

As you say it must be work (receiver and sender with mut), but also result in an infinite loop!

struct Dog {}
struct Cat {}

fn (mut d Dog) speak() { println('woof') }
fn (mut c Cat) speak() { println('meow') }

type Pet = Dog | Cat

fn (mut p Pet) speak() {
    println('Speak')
    match p {
        Dog { p.speak() }
        Cat { p.speak() }
    }
}

fn main() {
    mut pet := Pet(Cat{})
    pet.speak()
}

In my program 'Pet' is a Database and Dog (NoSql) and Cat (Sql) engines. Logically I need a mut Database to speak (Open).
I think would be the smartcast in this case would be of interest

@ejtizado you need match mut p because otherwise the smart cast is never performed which means p is the sum type Pet not Cat or Dog. So its an infinite loop of Pet.speak() which calls itself

You can see the condition which activates the smart cast here: https://github.com/vlang/v/blob/master/vlib/v/checker/checker.v#L3643. It could be that this needs more consideration.

I'm opening this again for now, as this behaviour is unclear and this may need more discussion

Thanks @joe-conigliaro . After update V it works fine.
Only an advise on the behaviour (as you say unclear). This also work:

struct Dog {}
struct Cat {}

fn (mut d Dog) speak() { println('woof') }
fn (mut c Cat) speak() { println('meow') }

type Pet = Dog | Cat

fn (p Pet) speak() {
    println('Speak')
    match mut p {
        Dog { p.speak() }
        Cat { p.speak() }
    }
}

fn main() {
    mut pet := Pet(Cat{})
    pet.speak()
}

it doesn't make sense that 'fn (p Pet)' is inmutable and then 'match' mark as mutable and send as mutable to Doc/Cat. speak()

No problem @ejtizado, thanks for bringing the issue to our attention.

You are correct about your previous comment, the compiler will need to error in this condition. I will get this sorted out.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

radare picture radare  路  3Comments

clpo13 picture clpo13  路  3Comments

radare picture radare  路  3Comments

cjmxp picture cjmxp  路  3Comments

lobotony picture lobotony  路  3Comments