@@ -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 ( ( ) )
@@ -1957,4 +1961,72 @@ fn main() {
19571961 "# ,
19581962 ) ;
19591963 }
1964+
1965+ #[ test]
1966+ fn prefer_underscore_import ( ) {
1967+ check_assist_by_label (
1968+ auto_import,
1969+ r#"
1970+ mod foo {
1971+ #[rust_analyzer::prefer_underscore_import]
1972+ pub trait Ext {
1973+ fn bar(&self) {}
1974+ }
1975+ impl<T> Ext for T {}
1976+ }
1977+
1978+ fn baz() {
1979+ 1.b$0ar();
1980+ }
1981+ "# ,
1982+ r#"
1983+ use foo::Ext as _;
1984+
1985+ mod foo {
1986+ #[rust_analyzer::prefer_underscore_import]
1987+ pub trait Ext {
1988+ fn bar(&self) {}
1989+ }
1990+ impl<T> Ext for T {}
1991+ }
1992+
1993+ fn baz() {
1994+ 1.bar();
1995+ }
1996+ "# ,
1997+ "Import `foo::Ext`" ,
1998+ ) ;
1999+ check_assist_by_label (
2000+ auto_import,
2001+ r#"
2002+ mod foo {
2003+ #[rust_analyzer::prefer_underscore_import]
2004+ pub trait Ext {
2005+ fn bar(&self) {}
2006+ }
2007+ impl<T> Ext for T {}
2008+ }
2009+
2010+ fn baz() {
2011+ 1.b$0ar();
2012+ }
2013+ "# ,
2014+ r#"
2015+ use foo::Ext;
2016+
2017+ mod foo {
2018+ #[rust_analyzer::prefer_underscore_import]
2019+ pub trait Ext {
2020+ fn bar(&self) {}
2021+ }
2022+ impl<T> Ext for T {}
2023+ }
2024+
2025+ fn baz() {
2026+ 1.bar();
2027+ }
2028+ "# ,
2029+ "Import `foo::Ext` without `as _`" ,
2030+ ) ;
2031+ }
19602032}
0 commit comments