about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-07-07 08:32:46 +0000
committerbors <bors@rust-lang.org>2024-07-07 08:32:46 +0000
commit9a04253016f03e021c94e94e68aea84f94af0919 (patch)
tree78055626c79ed05a7eaac1d860e1abf0625a2fa9
parent3c5595a06d9b82d9d44720c506fa85bad8275f99 (diff)
parentf398be1639e2d5b611d58625b78f0209adbd77f1 (diff)
downloadrust-9a04253016f03e021c94e94e68aea84f94af0919.tar.gz
rust-9a04253016f03e021c94e94e68aea84f94af0919.zip
Auto merge of #17523 - wada314:master, r=Veykril
Add an option to use "::" for the external crate prefix.

Fixes #11823 .
Hi I'm very new to rust-analyzer and not sure how the review process are. Can somebody take a look at this PR? thanks!
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/find_path.rs90
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/tests.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/config.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/lib.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs32
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use/tests.rs20
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs19
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs6
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs7
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs5
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs4
-rw-r--r--src/tools/rust-analyzer/docs/user/generated_config.adoc5
-rw-r--r--src/tools/rust-analyzer/editors/code/package.json10
43 files changed, 233 insertions, 11 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
index 58a1872ef25..9a3c0495414 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
@@ -183,6 +183,8 @@ fn find_path_for_module(
             let kind = if name_already_occupied_in_type_ns {
                 cov_mark::hit!(ambiguous_crate_start);
                 PathKind::Abs
+            } else if ctx.cfg.prefer_absolute {
+                PathKind::Abs
             } else {
                 PathKind::Plain
             };
@@ -564,7 +566,13 @@ mod tests {
     /// item the `path` refers to returns that same path when called from the
     /// module the cursor is in.
     #[track_caller]
-    fn check_found_path_(ra_fixture: &str, path: &str, prefer_prelude: bool, expect: Expect) {
+    fn check_found_path_(
+        ra_fixture: &str,
+        path: &str,
+        prefer_prelude: bool,
+        prefer_absolute: bool,
+        expect: Expect,
+    ) {
         let (db, pos) = TestDB::with_position(ra_fixture);
         let module = db.module_at_position(pos);
         let parsed_path_file =
@@ -604,7 +612,7 @@ mod tests {
                 module,
                 prefix,
                 ignore_local_imports,
-                ImportPathConfig { prefer_no_std: false, prefer_prelude },
+                ImportPathConfig { prefer_no_std: false, prefer_prelude, prefer_absolute },
             );
             format_to!(
                 res,
@@ -619,11 +627,15 @@ mod tests {
     }
 
     fn check_found_path(ra_fixture: &str, path: &str, expect: Expect) {
-        check_found_path_(ra_fixture, path, false, expect);
+        check_found_path_(ra_fixture, path, false, false, expect);
     }
 
     fn check_found_path_prelude(ra_fixture: &str, path: &str, expect: Expect) {
-        check_found_path_(ra_fixture, path, true, expect);
+        check_found_path_(ra_fixture, path, true, false, expect);
+    }
+
+    fn check_found_path_absolute(ra_fixture: &str, path: &str, expect: Expect) {
+        check_found_path_(ra_fixture, path, false, true, expect);
     }
 
     #[test]
@@ -871,6 +883,39 @@ pub mod ast {
     }
 
     #[test]
+    fn partially_imported_with_prefer_absolute() {
+        cov_mark::check!(partially_imported);
+        // Similar to partially_imported test case above, but with prefer_absolute enabled.
+        // Even if the actual imported item is in external crate, if the path to that item
+        // is starting from the imported name, then the path should not start from "::".
+        // i.e. The first line in the expected output should not start from "::".
+        check_found_path_absolute(
+            r#"
+//- /main.rs crate:main deps:syntax
+
+use syntax::ast;
+$0
+
+//- /lib.rs crate:syntax
+pub mod ast {
+    pub enum ModuleItem {
+        A, B, C,
+    }
+}
+        "#,
+            "syntax::ast::ModuleItem",
+            expect![[r#"
+                Plain  (imports ✔): ast::ModuleItem
+                Plain  (imports ✖): ::syntax::ast::ModuleItem
+                ByCrate(imports ✔): crate::ast::ModuleItem
+                ByCrate(imports ✖): ::syntax::ast::ModuleItem
+                BySelf (imports ✔): self::ast::ModuleItem
+                BySelf (imports ✖): ::syntax::ast::ModuleItem
+            "#]],
+        );
+    }
+
+    #[test]
     fn same_crate_reexport() {
         check_found_path(
             r#"
@@ -1770,6 +1815,43 @@ pub mod foo {
     }
 
     #[test]
+    fn respects_absolute_setting() {
+        let ra_fixture = r#"
+//- /main.rs crate:main deps:krate
+$0
+//- /krate.rs crate:krate
+pub mod foo {
+    pub struct Foo;
+}
+"#;
+        check_found_path(
+            ra_fixture,
+            "krate::foo::Foo",
+            expect![[r#"
+            Plain  (imports ✔): krate::foo::Foo
+            Plain  (imports ✖): krate::foo::Foo
+            ByCrate(imports ✔): krate::foo::Foo
+            ByCrate(imports ✖): krate::foo::Foo
+            BySelf (imports ✔): krate::foo::Foo
+            BySelf (imports ✖): krate::foo::Foo
+        "#]],
+        );
+
+        check_found_path_absolute(
+            ra_fixture,
+            "krate::foo::Foo",
+            expect![[r#"
+            Plain  (imports ✔): ::krate::foo::Foo
+            Plain  (imports ✖): ::krate::foo::Foo
+            ByCrate(imports ✔): ::krate::foo::Foo
+            ByCrate(imports ✖): ::krate::foo::Foo
+            BySelf (imports ✔): ::krate::foo::Foo
+            BySelf (imports ✖): ::krate::foo::Foo
+        "#]],
+        );
+    }
+
+    #[test]
     fn respect_segment_length() {
         check_found_path(
             r#"
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
index 211cdd35fd7..fc026a14d44 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
@@ -116,6 +116,8 @@ pub struct ImportPathConfig {
     pub prefer_no_std: bool,
     /// If true, prefer import paths containing a prelude module.
     pub prefer_prelude: bool,
+    /// If true, prefer abs path (starting with `::`) where it is available.
+    pub prefer_absolute: bool,
 }
 
 #[derive(Debug)]
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index 458970aa700..75508707e99 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -1043,7 +1043,11 @@ impl HirDisplay for Ty {
                             module_id,
                             PrefixKind::Plain,
                             false,
-                            ImportPathConfig { prefer_no_std: false, prefer_prelude: true },
+                            ImportPathConfig {
+                                prefer_no_std: false,
+                                prefer_prelude: true,
+                                prefer_absolute: false,
+                            },
                         ) {
                             write!(f, "{}", path.display(f.db.upcast()))?;
                         } else {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs
index 410237f9ca3..f1de6aba05b 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs
@@ -15,6 +15,7 @@ pub struct AssistConfig {
     pub insert_use: InsertUseConfig,
     pub prefer_no_std: bool,
     pub prefer_prelude: bool,
+    pub prefer_absolute: bool,
     pub assist_emit_must_use: bool,
     pub term_search_fuel: u64,
     pub term_search_borrowck: bool,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
index 22a4674fd46..4eb29a2378a 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
@@ -74,6 +74,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
     let cfg = ImportPathConfig {
         prefer_no_std: ctx.config.prefer_no_std,
         prefer_prelude: ctx.config.prefer_prelude,
+        prefer_absolute: ctx.config.prefer_absolute,
     };
 
     let module = ctx.sema.scope(expr.syntax())?.module();
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs
index fe895eb2598..f17635972b7 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs
@@ -93,6 +93,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
     let cfg = ImportPathConfig {
         prefer_no_std: ctx.config.prefer_no_std,
         prefer_prelude: ctx.config.prefer_prelude,
+        prefer_absolute: ctx.config.prefer_absolute,
     };
 
     let (import_assets, syntax_under_caret) = find_importable_node(ctx)?;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs
index 0aa23ccc840..f094c5c09f0 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs
@@ -340,6 +340,7 @@ fn augment_references_with_imports(
     let cfg = ImportPathConfig {
         prefer_no_std: ctx.config.prefer_no_std,
         prefer_prelude: ctx.config.prefer_prelude,
+        prefer_absolute: ctx.config.prefer_absolute,
     };
 
     references
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs
index be433c33338..92da2678f97 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs
@@ -47,6 +47,7 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext<'_>) -
     let cfg = ImportPathConfig {
         prefer_no_std: ctx.config.prefer_no_std,
         prefer_prelude: ctx.config.prefer_prelude,
+        prefer_absolute: ctx.config.prefer_absolute,
     };
 
     let src_type_path = {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs
index 241fc3b7a37..c55ff24ae38 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs
@@ -186,6 +186,7 @@ fn augment_references_with_imports(
     let cfg = ImportPathConfig {
         prefer_no_std: ctx.config.prefer_no_std,
         prefer_prelude: ctx.config.prefer_prelude,
+        prefer_absolute: ctx.config.prefer_absolute,
     };
 
     references
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs
index 76188715524..666e1a1496e 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs
@@ -90,6 +90,7 @@ fn collect_data(ident_pat: ast::IdentPat, ctx: &AssistContext<'_>) -> Option<Str
     let cfg = ImportPathConfig {
         prefer_no_std: ctx.config.prefer_no_std,
         prefer_prelude: ctx.config.prefer_prelude,
+        prefer_absolute: ctx.config.prefer_absolute,
     };
 
     let module = ctx.sema.scope(ident_pat.syntax())?.module();
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
index de447c1e338..20c37f92337 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
@@ -216,6 +216,7 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
                         ImportPathConfig {
                             prefer_no_std: ctx.config.prefer_no_std,
                             prefer_prelude: ctx.config.prefer_prelude,
+                            prefer_absolute: ctx.config.prefer_absolute,
                         },
                     );
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
index 3c6d73b62e7..54323e2928e 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -393,6 +393,7 @@ fn process_references(
                     ImportPathConfig {
                         prefer_no_std: ctx.config.prefer_no_std,
                         prefer_prelude: ctx.config.prefer_prelude,
+                        prefer_absolute: ctx.config.prefer_absolute,
                     },
                 );
                 if let Some(mut mod_path) = mod_path {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
index 9a441fc5ebc..cc33439dd59 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
@@ -64,6 +64,7 @@ fn generate_record_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
         ImportPathConfig {
             prefer_no_std: ctx.config.prefer_no_std,
             prefer_prelude: ctx.config.prefer_prelude,
+            prefer_absolute: ctx.config.prefer_absolute,
         },
     )?;
 
@@ -111,6 +112,7 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()
         ImportPathConfig {
             prefer_no_std: ctx.config.prefer_no_std,
             prefer_prelude: ctx.config.prefer_prelude,
+            prefer_absolute: ctx.config.prefer_absolute,
         },
     )?;
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs
index 52007e0e297..6056c808880 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs
@@ -65,6 +65,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
                     ImportPathConfig {
                         prefer_no_std: ctx.config.prefer_no_std,
                         prefer_prelude: ctx.config.prefer_prelude,
+                        prefer_absolute: ctx.config.prefer_absolute,
                     },
                 )?;
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs
index 5d1140d57ac..89e24fafc55 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs
@@ -53,6 +53,7 @@ pub(crate) fn qualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) ->
         ImportPathConfig {
             prefer_no_std: ctx.config.prefer_no_std,
             prefer_prelude: ctx.config.prefer_prelude,
+            prefer_absolute: ctx.config.prefer_absolute,
         },
     )?;
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs
index 978b719c30a..ca6c7c58b70 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs
@@ -40,6 +40,7 @@ pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
     let cfg = ImportPathConfig {
         prefer_no_std: ctx.config.prefer_no_std,
         prefer_prelude: ctx.config.prefer_prelude,
+        prefer_absolute: ctx.config.prefer_absolute,
     };
 
     let mut proposed_imports: Vec<_> =
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
index e792debaa51..5582256a170 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -89,6 +89,7 @@ pub(crate) fn replace_derive_with_manual_impl(
                 ImportPathConfig {
                     prefer_no_std: ctx.config.prefer_no_std,
                     prefer_prelude: ctx.config.prefer_prelude,
+                    prefer_absolute: ctx.config.prefer_absolute,
                 },
             )
             .as_ref()
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs
index 188165e7764..f1467837dd0 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs
@@ -70,6 +70,7 @@ pub(crate) fn replace_qualified_name_with_use(
                 ImportPathConfig {
                     prefer_no_std: ctx.config.prefer_no_std,
                     prefer_prelude: ctx.config.prefer_prelude,
+                    prefer_absolute: ctx.config.prefer_absolute,
                 },
             )
         })
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs
index 874b42f51b5..7a911799757 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs
@@ -60,6 +60,7 @@ pub(crate) fn term_search(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
                 ImportPathConfig {
                     prefer_no_std: ctx.config.prefer_no_std,
                     prefer_prelude: ctx.config.prefer_prelude,
+                    prefer_absolute: ctx.config.prefer_absolute,
                 },
             )
             .ok()
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs
index 30e09648ea1..f79f87db9a6 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs
@@ -142,6 +142,7 @@ pub(crate) fn desugar_async_into_impl_future(
         ImportPathConfig {
             prefer_no_std: ctx.config.prefer_no_std,
             prefer_prelude: ctx.config.prefer_prelude,
+            prefer_absolute: ctx.config.prefer_absolute,
         },
     )?;
     let trait_path = trait_path.display(ctx.db());
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs
index bd10b5481bb..2dcfda334b8 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs
@@ -30,6 +30,7 @@ pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig {
     },
     prefer_no_std: false,
     prefer_prelude: true,
+    prefer_absolute: false,
     assist_emit_must_use: false,
     term_search_fuel: 400,
     term_search_borrowck: true,
@@ -47,6 +48,7 @@ pub(crate) const TEST_CONFIG_NO_SNIPPET_CAP: AssistConfig = AssistConfig {
     },
     prefer_no_std: false,
     prefer_prelude: true,
+    prefer_absolute: false,
     assist_emit_must_use: false,
     term_search_fuel: 400,
     term_search_borrowck: true,
@@ -64,6 +66,7 @@ pub(crate) const TEST_CONFIG_IMPORT_ONE: AssistConfig = AssistConfig {
     },
     prefer_no_std: false,
     prefer_prelude: true,
+    prefer_absolute: false,
     assist_emit_must_use: false,
     term_search_fuel: 400,
     term_search_borrowck: true,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
index 11ffc8bc441..995a4443edf 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
@@ -639,6 +639,7 @@ fn enum_variants_with_paths(
             ImportPathConfig {
                 prefer_no_std: ctx.config.prefer_no_std,
                 prefer_prelude: ctx.config.prefer_prelude,
+                prefer_absolute: ctx.config.prefer_absolute,
             },
         ) {
             // Variants with trivial paths are already added by the existing completion logic,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
index 7281c607da4..01f9368aa4e 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
@@ -177,6 +177,7 @@ pub(crate) fn complete_expr_path(
                                 ImportPathConfig {
                                     prefer_no_std: ctx.config.prefer_no_std,
                                     prefer_prelude: ctx.config.prefer_prelude,
+                                    prefer_absolute: ctx.config.prefer_absolute,
                                 },
                             )
                             .filter(|it| it.len() > 1);
@@ -202,6 +203,7 @@ pub(crate) fn complete_expr_path(
                                 ImportPathConfig {
                                     prefer_no_std: ctx.config.prefer_no_std,
                                     prefer_prelude: ctx.config.prefer_prelude,
+                                    prefer_absolute: ctx.config.prefer_absolute,
                                 },
                             )
                             .filter(|it| it.len() > 1);
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs
index 71d44a57cb9..3a8b9c0cb97 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs
@@ -259,6 +259,7 @@ fn import_on_the_fly(
     let import_cfg = ImportPathConfig {
         prefer_no_std: ctx.config.prefer_no_std,
         prefer_prelude: ctx.config.prefer_prelude,
+        prefer_absolute: ctx.config.prefer_absolute,
     };
 
     import_assets
@@ -309,6 +310,7 @@ fn import_on_the_fly_pat_(
     let cfg = ImportPathConfig {
         prefer_no_std: ctx.config.prefer_no_std,
         prefer_prelude: ctx.config.prefer_prelude,
+        prefer_absolute: ctx.config.prefer_absolute,
     };
 
     import_assets
@@ -354,6 +356,7 @@ fn import_on_the_fly_method(
     let cfg = ImportPathConfig {
         prefer_no_std: ctx.config.prefer_no_std,
         prefer_prelude: ctx.config.prefer_prelude,
+        prefer_absolute: ctx.config.prefer_absolute,
     };
 
     import_assets
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
index 5041ef8d8a1..d919609237a 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
@@ -63,6 +63,7 @@ pub(crate) fn complete_postfix(
     let cfg = ImportPathConfig {
         prefer_no_std: ctx.config.prefer_no_std,
         prefer_prelude: ctx.config.prefer_prelude,
+        prefer_absolute: ctx.config.prefer_absolute,
     };
 
     if let Some(drop_trait) = ctx.famous_defs().core_ops_Drop() {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/config.rs b/src/tools/rust-analyzer/crates/ide-completion/src/config.rs
index 809c305ed82..7d062cb23e5 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/config.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/config.rs
@@ -22,6 +22,7 @@ pub struct CompletionConfig {
     pub insert_use: InsertUseConfig,
     pub prefer_no_std: bool,
     pub prefer_prelude: bool,
+    pub prefer_absolute: bool,
     pub snippets: Vec<Snippet>,
     pub limit: Option<usize>,
 }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
index 7150fe3f017..7d9c2c7c60d 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
@@ -253,6 +253,7 @@ pub fn resolve_completion_edits(
     let cfg = ImportPathConfig {
         prefer_no_std: config.prefer_no_std,
         prefer_prelude: config.prefer_prelude,
+        prefer_absolute: config.prefer_absolute,
     };
 
     imports.into_iter().for_each(|(full_import_path, imported_name)| {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
index b98f745f178..fe9e2e5268a 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
@@ -298,6 +298,7 @@ pub(crate) fn render_expr(
     let cfg = ImportPathConfig {
         prefer_no_std: ctx.config.prefer_no_std,
         prefer_prelude: ctx.config.prefer_prelude,
+        prefer_absolute: ctx.config.prefer_absolute,
     };
 
     let label = expr.gen_source_code(&ctx.scope, &mut label_formatter, cfg).ok()?;
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs b/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs
index 07836040b48..5885b74e09d 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs
@@ -172,6 +172,7 @@ fn import_edits(ctx: &CompletionContext<'_>, requires: &[GreenNode]) -> Option<V
     let import_cfg = ImportPathConfig {
         prefer_no_std: ctx.config.prefer_no_std,
         prefer_prelude: ctx.config.prefer_prelude,
+        prefer_absolute: ctx.config.prefer_absolute,
     };
 
     let resolve = |import: &GreenNode| {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs
index c1a67315b75..fcac6c7ce72 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs
@@ -79,6 +79,7 @@ pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig {
     },
     prefer_no_std: false,
     prefer_prelude: true,
+    prefer_absolute: false,
     snippets: Vec::new(),
     limit: None,
 };
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs
index abffa73c3b4..7d9c1ed98ac 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs
@@ -871,6 +871,38 @@ fn main() {
 }
 
 #[test]
+fn config_prefer_absolute() {
+    let fixture = r#"
+//- /lib.rs crate:dep
+pub mod foo {
+    pub mod bar {
+        pub struct Item;
+    }
+}
+
+//- /main.rs crate:main deps:dep
+use ::dep::foo::bar;
+
+fn main() {
+    Ite$0
+}"#;
+    let mut config = TEST_CONFIG;
+    config.prefer_absolute = true;
+
+    check_edit_with_config(
+        config.clone(),
+        "Item",
+        fixture,
+        r#"
+use ::dep::foo::bar::{self, Item};
+
+fn main() {
+    Item
+}"#,
+    );
+}
+
+#[test]
 fn unresolved_qualifier() {
     let fixture = r#"
 mod foo {
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use/tests.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use/tests.rs
index 9d1f1cc09c6..81604b55272 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use/tests.rs
@@ -1222,6 +1222,26 @@ use self::foo::{self, Bar, Foo};
     );
 }
 
+#[test]
+fn insert_with_double_colon_prefixed_import_merge() {
+    check_with_config(
+        "use ::ext::foo::Foo",
+        r#"
+use ::ext::foo::Foo as _;
+"#,
+        r#"
+use ::ext::foo::Foo;
+"#,
+        &InsertUseConfig {
+            granularity: ImportGranularity::Crate,
+            prefix_kind: hir::PrefixKind::BySelf,
+            enforce_granularity: true,
+            group: true,
+            skip_glob_imports: true,
+        },
+    );
+}
+
 fn check_with_config(
     path: &str,
     ra_fixture_before: &str,
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
index 7c11dd3e2a4..90c691ed6c9 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
@@ -308,8 +308,11 @@ impl Ctx<'_> {
                             parent.segment()?.name_ref()?,
                         )
                         .and_then(|trait_ref| {
-                            let cfg =
-                                ImportPathConfig { prefer_no_std: false, prefer_prelude: true };
+                            let cfg = ImportPathConfig {
+                                prefer_no_std: false,
+                                prefer_prelude: true,
+                                prefer_absolute: false,
+                            };
                             let found_path = self.target_module.find_path(
                                 self.source_scope.db.upcast(),
                                 hir::ModuleDef::Trait(trait_ref),
@@ -348,7 +351,11 @@ impl Ctx<'_> {
                     }
                 }
 
-                let cfg = ImportPathConfig { prefer_no_std: false, prefer_prelude: true };
+                let cfg = ImportPathConfig {
+                    prefer_no_std: false,
+                    prefer_prelude: true,
+                    prefer_absolute: false,
+                };
                 let found_path =
                     self.target_module.find_path(self.source_scope.db.upcast(), def, cfg)?;
                 let res = mod_path_to_ast(&found_path).clone_for_update();
@@ -383,7 +390,11 @@ impl Ctx<'_> {
 
                 if let Some(adt) = ty.as_adt() {
                     if let ast::Type::PathType(path_ty) = &ast_ty {
-                        let cfg = ImportPathConfig { prefer_no_std: false, prefer_prelude: true };
+                        let cfg = ImportPathConfig {
+                            prefer_no_std: false,
+                            prefer_prelude: true,
+                            prefer_absolute: false,
+                        };
                         let found_path = self.target_module.find_path(
                             self.source_scope.db.upcast(),
                             ModuleDef::from(adt),
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
index 2b8779044fb..a9c0e3b7319 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
@@ -146,6 +146,7 @@ pub(crate) fn json_in_items(
                         let cfg = ImportPathConfig {
                             prefer_no_std: config.prefer_no_std,
                             prefer_prelude: config.prefer_prelude,
+                            prefer_absolute: config.prefer_absolute,
                         };
 
                         if !scope_has("Serialize") {
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs
index 9eff84b8987..6a809cb0cef 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs
@@ -128,6 +128,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass
                             ImportPathConfig {
                                 prefer_no_std: ctx.config.prefer_no_std,
                                 prefer_prelude: ctx.config.prefer_prelude,
+                                prefer_absolute: ctx.config.prefer_absolute,
                             },
                         )?;
 
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs
index a64bac29498..4f04267adb1 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs
@@ -67,6 +67,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Option<Vec<Assist>
                 ImportPathConfig {
                     prefer_no_std: ctx.config.prefer_no_std,
                     prefer_prelude: ctx.config.prefer_prelude,
+                    prefer_absolute: ctx.config.prefer_absolute,
                 },
             )
             .ok()
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
index eb8e8e91d0e..6d1226d65c5 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
@@ -231,6 +231,7 @@ pub struct DiagnosticsConfig {
     pub insert_use: InsertUseConfig,
     pub prefer_no_std: bool,
     pub prefer_prelude: bool,
+    pub prefer_absolute: bool,
     pub term_search_fuel: u64,
     pub term_search_borrowck: bool,
 }
@@ -258,6 +259,7 @@ impl DiagnosticsConfig {
             },
             prefer_no_std: false,
             prefer_prelude: true,
+            prefer_absolute: false,
             term_search_fuel: 400,
             term_search_borrowck: true,
         }
diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
index b29053c0c2d..0d22bc94c61 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
+++ b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
@@ -663,7 +663,11 @@ impl Match {
             .module();
         for (path, resolved_path) in &template.resolved_paths {
             if let hir::PathResolution::Def(module_def) = resolved_path.resolution {
-                let cfg = ImportPathConfig { prefer_no_std: false, prefer_prelude: true };
+                let cfg = ImportPathConfig {
+                    prefer_no_std: false,
+                    prefer_prelude: true,
+                    prefer_absolute: false,
+                };
                 let mod_path = module.find_path(sema.db, module_def, cfg).ok_or_else(|| {
                     match_error!("Failed to render template path `{}` at match location")
                 })?;
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
index c9c19806bef..16a880e18bf 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -439,7 +439,11 @@ impl flags::AnalysisStats {
                         .gen_source_code(
                             &scope,
                             &mut formatter,
-                            ImportPathConfig { prefer_no_std: false, prefer_prelude: true },
+                            ImportPathConfig {
+                                prefer_no_std: false,
+                                prefer_prelude: true,
+                                prefer_absolute: false,
+                            },
                         )
                         .unwrap();
                     syntax_hit_found |= trim(&original_text) == trim(&generated);
@@ -988,6 +992,7 @@ impl flags::AnalysisStats {
                     },
                     prefer_no_std: false,
                     prefer_prelude: true,
+                    prefer_absolute: false,
                     style_lints: false,
                     term_search_fuel: 400,
                     term_search_borrowck: true,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index 948bc2c6c77..94e01158629 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -357,6 +357,8 @@ config_data! {
         imports_preferPrelude: bool                       = false,
         /// The path structure for newly inserted paths to use.
         imports_prefix: ImportPrefixDef               = ImportPrefixDef::Plain,
+        /// Whether to prefix external (including std, core) crate imports with `::`. e.g. "use ::std::io::Read;".
+        imports_prefixExternPrelude: bool = false,
     }
 }
 
@@ -1270,6 +1272,7 @@ impl Config {
             prefer_no_std: self.imports_preferNoStd(source_root).to_owned(),
             assist_emit_must_use: self.assist_emitMustUse(source_root).to_owned(),
             prefer_prelude: self.imports_preferPrelude(source_root).to_owned(),
+            prefer_absolute: self.imports_prefixExternPrelude(source_root).to_owned(),
             term_search_fuel: self.assist_termSearch_fuel(source_root).to_owned() as u64,
             term_search_borrowck: self.assist_termSearch_borrowcheck(source_root).to_owned(),
         }
@@ -1292,6 +1295,7 @@ impl Config {
             insert_use: self.insert_use_config(source_root),
             prefer_no_std: self.imports_preferNoStd(source_root).to_owned(),
             prefer_prelude: self.imports_preferPrelude(source_root).to_owned(),
+            prefer_absolute: self.imports_prefixExternPrelude(source_root).to_owned(),
             snippets: self.snippets.clone().to_vec(),
             limit: self.completion_limit().to_owned(),
             enable_term_search: self.completion_termSearch_enable().to_owned(),
@@ -1320,6 +1324,7 @@ impl Config {
             insert_use: self.insert_use_config(source_root),
             prefer_no_std: self.imports_preferNoStd(source_root).to_owned(),
             prefer_prelude: self.imports_preferPrelude(source_root).to_owned(),
+            prefer_absolute: self.imports_prefixExternPrelude(source_root).to_owned(),
             style_lints: self.diagnostics_styleLints_enable().to_owned(),
             term_search_fuel: self.assist_termSearch_fuel(source_root).to_owned() as u64,
             term_search_borrowck: self.assist_termSearch_borrowcheck(source_root).to_owned(),
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs
index 65fbc96dad3..ff8eb6c8612 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs
@@ -152,6 +152,7 @@ fn integrated_completion_benchmark() {
             },
             prefer_no_std: false,
             prefer_prelude: true,
+            prefer_absolute: false,
             snippets: Vec::new(),
             limit: None,
         };
@@ -197,6 +198,7 @@ fn integrated_completion_benchmark() {
             },
             prefer_no_std: false,
             prefer_prelude: true,
+            prefer_absolute: false,
             snippets: Vec::new(),
             limit: None,
         };
@@ -240,6 +242,7 @@ fn integrated_completion_benchmark() {
             },
             prefer_no_std: false,
             prefer_prelude: true,
+            prefer_absolute: false,
             snippets: Vec::new(),
             limit: None,
         };
@@ -299,6 +302,7 @@ fn integrated_diagnostics_benchmark() {
         },
         prefer_no_std: false,
         prefer_prelude: false,
+        prefer_absolute: false,
         term_search_fuel: 400,
         term_search_borrowck: true,
     };
diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc
index ea86d21e47f..a95c897991d 100644
--- a/src/tools/rust-analyzer/docs/user/generated_config.adoc
+++ b/src/tools/rust-analyzer/docs/user/generated_config.adoc
@@ -594,6 +594,11 @@ Whether to prefer import paths containing a `prelude` module.
 --
 The path structure for newly inserted paths to use.
 --
+[[rust-analyzer.imports.prefixExternPrelude]]rust-analyzer.imports.prefixExternPrelude (default: `false`)::
++
+--
+Whether to prefix external (including std, core) crate imports with `::`. e.g. "use ::std::io::Read;".
+--
 [[rust-analyzer.inlayHints.bindingModeHints.enable]]rust-analyzer.inlayHints.bindingModeHints.enable (default: `false`)::
 +
 --
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index 8d272246f0f..1fec6f621d1 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -1735,6 +1735,16 @@
                 }
             },
             {
+                "title": "imports",
+                "properties": {
+                    "rust-analyzer.imports.prefixExternPrelude": {
+                        "markdownDescription": "Whether to prefix external (including std, core) crate imports with `::`. e.g. \"use ::std::io::Read;\".",
+                        "default": false,
+                        "type": "boolean"
+                    }
+                }
+            },
+            {
                 "title": "inlayHints",
                 "properties": {
                     "rust-analyzer.inlayHints.bindingModeHints.enable": {