Lyricdev
GitHub

LYR-SEM0142

a 'catch' clause no error can reach

error · spec 06-errors

A 'catch' clause names a type every value of which is already taken by an earlier clause — typically an interface caught before one of its conformers.

Explanation

Clauses are tried top to bottom. When an earlier clause catches an interface (IoError), it takes every error of a type that conforms to it, so a later clause for a conformer (Disk) never runs. This is an error, not a warning, because the order almost always says the opposite of what was meant.

Put the clause for the more specific type first, or drop it.

Wrong

interface IoError :: [Error] { }

class Disk :: [IoError] {
    fn message(): string { return "disk"; }
}

fn read(): int throws Disk { return 1; }

fn main(): void {
    try {
        let _ = read();
    } catch (_: IoError) {
        return;
    } catch (_: Disk) {
        return;
    }
}
interface IoError :: [Error] { }

class Disk :: [IoError] {
    fn message(): string { return "disk"; }
}

fn read(): int throws Disk { return 1; }

fn main(): void {
    try {
        let _ = read();
    } catch (_: Disk) {
        return;
    } catch (_: IoError) {
        return;
    }
}