@@ -6,7 +6,7 @@ use ide_db::{
66 active_parameter:: ActiveParameter ,
77 helpers:: mod_path_to_ast,
88 imports:: {
9- import_assets:: { ImportAssets , ImportCandidate , LocatedImport } ,
9+ import_assets:: { ImportAssets , ImportCandidate , LocatedImport , TraitImportCandidate } ,
1010 insert_use:: { ImportScope , insert_use, insert_use_as_alias} ,
1111 } ,
1212} ;
@@ -123,44 +123,48 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
123123
124124 let ( assist_id, import_name) =
125125 ( AssistId :: quick_fix ( "auto_import" ) , import_path. display ( ctx. db ( ) , edition) ) ;
126- acc. add_group (
127- & group_label,
128- assist_id,
129- format ! ( "Import `{import_name}`" ) ,
130- range,
131- |builder| {
126+ let add_normal_import = |acc : & mut Assists , label| {
127+ acc. add_group ( & group_label, assist_id, label, range, |builder| {
132128 let scope = builder. make_import_scope_mut ( scope. clone ( ) ) ;
133129 insert_use ( & scope, mod_path_to_ast ( & import_path, edition) , & ctx. config . insert_use ) ;
134- } ,
135- ) ;
136-
137- match import_assets. import_candidate ( ) {
138- ImportCandidate :: TraitAssocItem ( name) | ImportCandidate :: TraitMethod ( name) => {
139- let is_method =
140- matches ! ( import_assets. import_candidate( ) , ImportCandidate :: TraitMethod ( _) ) ;
141- let type_ = if is_method { "method" } else { "item" } ;
142- let group_label = GroupLabel ( format ! (
143- "Import a trait for {} {} by alias" ,
144- type_,
145- name. assoc_item_name. text( )
146- ) ) ;
147- acc. add_group (
148- & group_label,
149- assist_id,
150- format ! ( "Import `{import_name} as _`" ) ,
151- range,
152- |builder| {
153- let scope = builder. make_import_scope_mut ( scope. clone ( ) ) ;
154- insert_use_as_alias (
155- & scope,
156- mod_path_to_ast ( & import_path, edition) ,
157- & ctx. config . insert_use ,
158- edition,
159- ) ;
160- } ,
130+ } )
131+ } ;
132+ let add_underscore_import = |acc : & mut Assists , name : & TraitImportCandidate < ' _ > , label| {
133+ let is_method =
134+ matches ! ( import_assets. import_candidate( ) , ImportCandidate :: TraitMethod ( _) ) ;
135+ let type_ = if is_method { "method" } else { "item" } ;
136+ let group_label = GroupLabel ( format ! (
137+ "Import a trait for {} {} by alias" ,
138+ type_,
139+ name. assoc_item_name. text( )
140+ ) ) ;
141+ acc. add_group ( & group_label, assist_id, label, range, |builder| {
142+ let scope = builder. make_import_scope_mut ( scope. clone ( ) ) ;
143+ insert_use_as_alias (
144+ & scope,
145+ mod_path_to_ast ( & import_path, edition) ,
146+ & ctx. config . insert_use ,
147+ edition,
161148 ) ;
162- }
163- _ => { }
149+ } ) ;
150+ } ;
151+
152+ if let ImportCandidate :: TraitAssocItem ( name) | ImportCandidate :: TraitMethod ( name) =
153+ import_assets. import_candidate ( )
154+ {
155+ if let hir:: ItemInNs :: Types ( hir:: ModuleDef :: Trait ( trait_to_import) ) =
156+ import. item_to_import
157+ && trait_to_import. prefer_underscore_import ( ctx. db ( ) )
158+ {
159+ // Flip the order of the suggestions and show a preference for `as _` in the name.
160+ add_underscore_import ( acc, name, format ! ( "Import `{import_name}`" ) ) ;
161+ add_normal_import ( acc, format ! ( "Import `{import_name}` without `as _`" ) ) ;
162+ } else {
163+ add_normal_import ( acc, format ! ( "Import `{import_name}`" ) ) ;
164+ add_underscore_import ( acc, name, format ! ( "Import `{import_name} as _`" ) ) ;
165+ }
166+ } else {
167+ add_normal_import ( acc, format ! ( "Import `{import_name}`" ) ) ;
164168 }
165169 }
166170 Some ( ( ) )
@@ -1928,4 +1932,72 @@ fn f() {
19281932 "# ;
19291933 check_auto_import_order ( before, & [ "Import `foo::wanted`" , "Import `quux::wanted`" ] ) ;
19301934 }
1935+
1936+ #[ test]
1937+ fn prefer_underscore_import ( ) {
1938+ check_assist_by_label (
1939+ auto_import,
1940+ r#"
1941+ mod foo {
1942+ #[rust_analyzer::prefer_underscore_import]
1943+ pub trait Ext {
1944+ fn bar(&self) {}
1945+ }
1946+ impl<T> Ext for T {}
1947+ }
1948+
1949+ fn baz() {
1950+ 1.b$0ar();
1951+ }
1952+ "# ,
1953+ r#"
1954+ use foo::Ext as _;
1955+
1956+ mod foo {
1957+ #[rust_analyzer::prefer_underscore_import]
1958+ pub trait Ext {
1959+ fn bar(&self) {}
1960+ }
1961+ impl<T> Ext for T {}
1962+ }
1963+
1964+ fn baz() {
1965+ 1.bar();
1966+ }
1967+ "# ,
1968+ "Import `foo::Ext`" ,
1969+ ) ;
1970+ check_assist_by_label (
1971+ auto_import,
1972+ r#"
1973+ mod foo {
1974+ #[rust_analyzer::prefer_underscore_import]
1975+ pub trait Ext {
1976+ fn bar(&self) {}
1977+ }
1978+ impl<T> Ext for T {}
1979+ }
1980+
1981+ fn baz() {
1982+ 1.b$0ar();
1983+ }
1984+ "# ,
1985+ r#"
1986+ use foo::Ext;
1987+
1988+ mod foo {
1989+ #[rust_analyzer::prefer_underscore_import]
1990+ pub trait Ext {
1991+ fn bar(&self) {}
1992+ }
1993+ impl<T> Ext for T {}
1994+ }
1995+
1996+ fn baz() {
1997+ 1.bar();
1998+ }
1999+ "# ,
2000+ "Import `foo::Ext` without `as _`" ,
2001+ ) ;
2002+ }
19312003}
0 commit comments