rust-analyzer icon indicating copy to clipboard operation
rust-analyzer copied to clipboard

Incorrect function deduced with same name as correct function

Open Zannick opened this issue 1 year ago • 4 comments

This seems to be a regression of #11048, and honestly, it's been a problem on and off for all of 2023.

In code like:

        scores
            .into_iter()
            .filter_map(|u| u)
            .min()

where scores is a Vec<Option<u32>>, rust-analyzer may assume that .min refers to a trait function defined in core::cmp::Ord (pub fn min(self, other: Self) -> Self) while the actual function in question is the Iterator trait function, which takes 0 additional arguments. The result is that VSCode complains that my code will not compile, but there is no problem with it.

The code is annotated like this:

        scores  Vec<Option<u32>>
            .into_iter()  IntoIter<Option<u32>>
            .filter_map(|u: Option<u32>| u)  impl Iterator<Item = u32>
            .min()  impl Iterator<Item = u32>

which is incorrect in the last line (but at least consistent with the assumption that the appropriate min is a comparison to another Iterator).

This also occurs with traits defined in the current crate. https://github.com/Zannick/logic-graph/blob/0cb411f89d36507e1f459599044725f43ca4669d/analyzer/src/condense.rs#L303 Changing Exit::dest(e) here to e.dest() results in rust-analyzer believing that this function is Action::dest. These trait functions have the same name but different arguments; Action is the first trait alphabetically in the same file as Exit that has a dest function.

After a rustup update and a restart of VSCode, the problem went away for these two examples but appeared elsewhere: warp.dest(ctx.get(), world) reports an error because rust-analyzer believes this refers to Exit::dest. rust-analyzer describes the type of warp.dest(ctx.get(), world) when I highlight it as <<W as World>::Warp as Exit>::SpotId. It annotates warp correctly as &<W as World>::Warp; the function has a type restriction on that associated type pointing to the correct trait with a dest function: W::Warp: Warp, so I'm not sure where this analysis can conclude that Exit trait functions can be invoked on warp.

rust-analyzer version: rust-analyzer version: 0.3.1823-standalone (7219414e8 2024-01-27)

rustc version: (as run from the VSCode terminal) rustc 1.74.0 (79e9716c9 2023-11-13), after rustup update rustc 1.75.0 (82e1608df 2023-12-21)

relevant settings: (eg. client settings, or environment variables like CARGO, RUSTC, RUSTUP_HOME or CARGO_HOME)

Zannick avatar Jan 30 '24 04:01 Zannick

Here's a quite absurd example that illustrates how it makes it hard to work with:

Screenshot 2024-02-15 193523

The code above boils down to:

let skippable = solution.history.iter().position(|h| [...]).unwrap_or(1);

where solution.history is a vector, and position is the Iterator trait function. This appears in a crate where another module defines a Ctx trait that defines fn position(&self);, hence the entire lambda is reported as an error "expected 0 arguments, found 1". Meanwhile, rust-analyzer correctly deduces the type of the lambda argument (well, mostly) and elements within the lambda, as in the picture above.

In the middle of this lambda, I'd originally written world.get_exit(exit_id) which was an error—the correct version is world.get_exit(*exit_id) (because exit_id is a reference and the function expects the value by copy). Due to the false-positive red squiggle across the whole lambda, I wasn't able to detect this until initiating a compile on my own.

Zannick avatar Feb 16 '24 03:02 Zannick

Probably another instance of https://github.com/rust-lang/chalk/issues/727 or https://github.com/rust-lang/chalk/issues/750; it will probably get fixed with the new trait solver (and not before).

flodiebold avatar Feb 17 '24 09:02 flodiebold

@flodiebold is there a tracking issue or something that we can follow for progress on the new trait solver?

programmerjake avatar May 23 '24 05:05 programmerjake