rust-lang / rust-analyzer

A Rust compiler front-end for IDEs
https://rust-analyzer.github.io/
Apache License 2.0
14.26k stars 1.61k forks source link

Output type of aliased Fn trait object is not inferred correctly. #13169

Open lucidfrontier45 opened 2 years ago

lucidfrontier45 commented 2 years ago

image

As is shown in the picture, the return type of dyn Fn trait objects is not correctly inferred. v in test_myfn_dyn and test_myfn2_dyn are also expected to be inferred as usize.

This may be related to https://github.com/rust-lang/rust-analyzer/issues/5057 but that was about directly writing dyn trait object, which works fine as the example of test_dyn_fn_trait_direct.

lowr commented 2 years ago

Interesting. Essentially, this is because chalk cannot prove Implemented(dyn Trait: Trait) given the following setup:

trait Base { type T; }
trait Trait: Base<T = usize> {}

Because of the rules described in https://github.com/rust-lang/chalk/issues/203, chalk needs to prove AliasEq(<dyn Trait as Base>::T = usize) only to fail as there's no clause for it.

@flodiebold Do you have any insights on this? I don't know chalk enough to tell if this is something chalk should be able to deduce by itself or if we need to give chalk more information, e.g. dyn for<Self> [Implemented(Self: Trait), AliasEq(<Self as Base>::T = usize)] for dyn Trait with the setup above whereas we currently only give dyn for<Self> [Implemented(Self: Trait)].

flodiebold commented 2 years ago

Well, that seems wrong. It seems to me that associated type bindings should be implied, not required. It certainly wouldn't make any sense for us to add that clause, since that's what implied bounds / elaboration are for. I'd suggest opening a Chalk issue for it.