Stream: t-compiler/rust-analyzer

Topic: De Morgan's Law with multiple terms


Jake Goulding (Mar 05 2021 at 00:23, on Zulip):

If I have (b != 0x09 && b != 0x0A && b != 0x0D), should I be able to change that into !(b == 0x09 || b == 0x0A || b == 0x0D) ? I'm just getting it to apply to two of the terms.

Mario Carneiro (Mar 05 2021 at 08:16, on Zulip):

Yes. I think clippy will yell at you for this pattern though, and suggest something like ![0x09, 0x0A, 0x0D].contains(&b), or I guess !b"\t\r\n".contains(&b) if I remember my ascii. (EDIT: misread the context, this is off-topic)

Lukas Wirth (Mar 05 2021 at 08:52, on Zulip):

the assist currently only applies it for the two terms that are part of the operator your cursor is on

matklad (Mar 05 2021 at 08:54, on Zulip):

You absolutely should, if you can not, that's a bug in https://github.com/matklad/rust-analyzer/blob/142f9a03fd4bad366439b18d8de7f2237bed65ab/crates/ide_assists/src/handlers/apply_demorgan.rs#L1

Jake Goulding (Mar 05 2021 at 14:08, on Zulip):

My experience mirror's @Lukas Wirth's — it only applies to the two terms around the one operator. I am using this via emacs, so I'd appreciate it if someone with Visual Studio could confirm if it affects them as well. If it does, I'll file an issue.

matklad (Mar 05 2021 at 14:10, on Zulip):

that should be independent of Emacs

matklad (Mar 05 2021 at 14:11, on Zulip):

we just need to handle that extra case, shouldn't be too hard. Perhaps you want to file a PR ^^ ?

Jake Goulding (Mar 05 2021 at 14:52, on Zulip):

I assume that a && b && c is (Binary (Binary a b) c) (or similar nesting); is there something that will easily look up and down the tree to get all of the terms at the same semantic level?

Lukas Wirth (Mar 05 2021 at 14:53, on Zulip):

RA offers a command Show Syntax Tree but I think that is only supported in vscode

Lukas Wirth (Mar 05 2021 at 14:54, on Zulip):

The tree for that is

            BIN_EXPR@7219..7230
              BIN_EXPR@7219..7225
                PATH_EXPR@7219..7220
                  PATH@7219..7220
                    PATH_SEGMENT@7219..7220
                      NAME_REF@7219..7220
                        IDENT@7219..7220 "a"
                WHITESPACE@7220..7221 " "
                AMP2@7221..7223 "&&"
                WHITESPACE@7223..7224 " "
                PATH_EXPR@7224..7225
                  PATH@7224..7225
                    PATH_SEGMENT@7224..7225
                      NAME_REF@7224..7225
                        IDENT@7224..7225 "b"
              WHITESPACE@7225..7226 " "
              AMP2@7226..7228 "&&"
              WHITESPACE@7228..7229 " "
              PATH_EXPR@7229..7230
                PATH@7229..7230
                  PATH_SEGMENT@7229..7230
                    NAME_REF@7229..7230
                      IDENT@7229..7230 "c"
Lukas Wirth (Mar 05 2021 at 14:54, on Zulip):

so ye its ((a && b) && c) nesting-wise

Lukas Wirth (Mar 05 2021 at 14:55, on Zulip):

you can walk the tree for next and prev let me check quickly how that goes

Lukas Wirth (Mar 05 2021 at 14:57, on Zulip):

Ah wait up and down, you can go up with ancestors and down with children if you mean that

Lukas Wirth (Mar 05 2021 at 14:58, on Zulip):

you have to invoke those on SyntaxNodes, so if you got an expression you'd be able to go up/down by doing expr.syntax().ancestors()

Jake Goulding (Mar 05 2021 at 15:00, on Zulip):

it starts with let expr = ctx.find_node_at_offset::<ast::BinExpr>()?;.

I'm thinking I basically need to see if either lhs or rhs is another binexpr with the same operator, or if I'm part of a binexpr with the same operator. That's what I mean by "up"/"down".

Lukas Wirth (Mar 05 2021 at 15:05, on Zulip):

Ah right, going down should be simple since you can directly insepect the sub expressions https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/syntax/src/ast/expr_ext.rs#L171-L232.
But going up seems a bit more tricky I suppose, let me think for a sec

matklad (Mar 05 2021 at 15:06, on Zulip):

expr.parent().and_then(ast::BinExpr::cast)

Lukas Wirth (Mar 05 2021 at 15:07, on Zulip):

right, its actually rather simple I confused myself there :big_smile:

Lukas Wirth (Mar 05 2021 at 15:08, on Zulip):

Though you have to put a syntax call in between, expr.syntax().parent()

Florian Diebold (Mar 05 2021 at 15:16, on Zulip):

Lukas Wirth said:

RA offers a command Show Syntax Tree but I think that is only supported in vscode

it's supported in Emacs: lsp-rust-analyzer-syntax-tree

Jake Goulding (Mar 05 2021 at 15:34, on Zulip):

What determines if code goes outside the call to Assists::add or inside? E.g. this code computes lhs and not_lhs outside. Just to make use of ??

matklad (Mar 05 2021 at 15:34, on Zulip):

Yup

matklad (Mar 05 2021 at 15:35, on Zulip):

the code outside can return None (meaning the assist doesn't apply)

matklad (Mar 05 2021 at 15:35, on Zulip):

the code insided should not fail and should compute the actual edit

matklad (Mar 05 2021 at 15:35, on Zulip):

(see https://rust-analyzer.github.io/blog/2020/09/28/how-to-make-a-light-bulb.html for somewhat amusing explanation of the shape of this api
)

Jake Goulding (Mar 05 2021 at 15:37, on Zulip):

and presumably lhs can be None if we have malformed input?

Laurențiu (Mar 05 2021 at 15:38, on Zulip):

Yes

Jake Goulding (Mar 05 2021 at 16:04, on Zulip):

Just going to repeat this every so often:

shouldn't be too hard

matklad (Mar 05 2021 at 16:10, on Zulip):

You just need to invest enough time to makes sure that sunk cost fallacy prevents you from bailing out :)

Josh Mcguigan (Mar 05 2021 at 18:17, on Zulip):

Florian Diebold said:

Lukas Wirth said:

RA offers a command Show Syntax Tree but I think that is only supported in vscode

it's supported in Emacs: lsp-rust-analyzer-syntax-tree

also in coc.vim with :CocCommand rust-analyzer.syntaxTree

Jake Goulding (Mar 05 2021 at 21:16, on Zulip):

I have something quite ugly but passing tests — open a PR, draft PR, just drop a link here, other?

Jake Goulding (Mar 05 2021 at 21:21, on Zulip):

My guess is that someone more familiar with navigating the trees will say "oh, use <this function> to clean up that cruft".

Jake Goulding (Mar 05 2021 at 21:22, on Zulip):

https://github.com/shepmaster/rust-analyzer/tree/multiple-demorgan to start with.

Lukas Wirth (Mar 06 2021 at 11:26, on Zulip):

Seems good to me

Last update: Jul 29 2021 at 07:45UTC