Stream: bugs

Topic: roc docs - incorrect generated annotation


view this post on Zulip Jonathan (Jul 15 2026 at 12:18):

I was looking through the docs for the basic-cli rc and saw the following invalid syntax as an annotation:

parser_for : encoding -> state -> Try({ value : Url, rest : state }, err)
and
encoder_for : encoding -> Url, state -> Try(state, err)

The parentheses seem to have been dropped that group the returned functions. The correct annotations (as in the source) would be

parser_for : encoding -> (state -> Try({ value : Url, rest : state }, err))
and
encoder_for : encoding -> (Url, state -> Try(state, err))


I would have put a PR in for this except that I became a bit confused about the binding of commas in bare parens vs in tags. E.g.
Foo(a, a -> a) is parsed to two payload types, a and a unary function a -> a, whereas : (a, a -> a) and : ((a, a -> a), ) parse to a plain binary function. Meanwhile, if you write

    p3 : (I32, (I32 -> I32))
    p3 = |a, b| a + b

The compiler will (correctly) tell you that the body doesn't match the annotation type, but will tell you in the error:

But the annotation says it should be:

        (I32, I32 -> I32)

As written, that suggestion will parse to a binary function that p3's body satisfies.


Anyhow, that is to say

view this post on Zulip Anton (Jul 15 2026 at 13:35):

Yes, the rule should be any function type gets parenthesized in every position except a top-level annotation slot, and neither printer (docs or error) implements that fully.

view this post on Zulip Anton (Jul 15 2026 at 13:37):

neither printer (docs or error)

Maybe these need to share code :thinking:

view this post on Zulip Anton (Jul 15 2026 at 13:38):

This seems reasonable as is for me

view this post on Zulip Jonathan (Jul 15 2026 at 13:46):

This seems reasonable as is for me

Yeh I think it was surprising until I realised that was the overall rule, and that it was consistent within tags and within bare parens.

Yes, the rule should be any function type gets parenthesized in every position except a top-level annotation slot, and neither printer (docs or error) implements that fully.

I think the fix for docs' render_type.zig is fairly simple at least, just flip needs_parens to true by default except at the top level, and except for within .parens.


Last updated: Jul 23 2026 at 13:15 UTC