-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
Currently when completing function items, whether arguments are expanded is controlled globally by rust-analyzer.completion.callable.snippets. Instead it should be based on the excepted type in the context the completion:
- If the return type of the expanded function could be applicable and the function item cannot, i.e. there exists a combination of generics given to the function that will satisfy the bounds of the function it is used in, the expanded form is used
- Otherwise, If the function item itself could be applicable the unexpanded form is used
- Otherwise or if the bounds cannot be solved, it should fallback to the existing setting
The main motivation is adding systems in bevy (i.e. App::add_systems),
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, set|)
.run();
}
fn setup(mut commands: Commands) {
commands.spawn(Camera2d::default());
}use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup([commands]);)
.run();
}
fn setup(mut commands: Commands) {
commands.spawn(Camera2d::default());
}(where [] represents the selection)
I would expect it to complete:
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup|)
.run();
}
fn setup(mut commands: Commands) {
commands.spawn(Camera2d::default());
}This case is simpler because the return type is () so we know it's never applicable.
As another example, completing arguments of std::convert::identity and std::hint::black_box it should be based on rust-analyzer.completion.callable.snippets, as both forms are applicable to the trait bounds.
Alternative: Attribute hints
If solving bounds isn't feasible in terms of complexity and performance, attributes that hint the intent could be used instead.
There are a couple of ways this could be done (terribly bikesheding syntax):
#[rust_analyzer::completion::callable::snippets(None)]to apply therust-analyzer.completion.callable.snippetssetting to an individual block#[rust_analyzer::completion::callable::arguments("functions")]to hint the function commonly expects functions as arguments#[rust_analyzer::completion::callable::expand(false)]to hint the function itself is commonly used as an argument
This won't work properly for higher order functions but it would still provide a much better experience for the bevy use case.