about summary refs log tree commit diff
path: root/src/tools
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2025-01-25 11:34:36 +0000
committerGitHub <noreply@github.com>2025-01-25 11:34:36 +0000
commit58401ab0c8cbbcc7f77d79fcc3fbebf241490f6b (patch)
treec2e5c4dda5f383661bebd87cdf44a24e8be64689 /src/tools
parentf45b8ad7f8764d2fbdd3ce90028b700ba1a3022f (diff)
parent0db8d05b5258f634c1c33551e104818338abd63b (diff)
downloadrust-58401ab0c8cbbcc7f77d79fcc3fbebf241490f6b.tar.gz
rust-58401ab0c8cbbcc7f77d79fcc3fbebf241490f6b.zip
Merge pull request #19028 from Veykril/push-vuytpkvqzwzs
fix: Fix flyimport not filtering via stability of import path
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/find_path.rs25
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lib.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/config.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs35
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs3
-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.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs1
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs1
21 files changed, 89 insertions, 20 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 5d67902c8ac..c30ad0163b9 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
@@ -445,6 +445,10 @@ fn find_in_dep(
         };
         cov_mark::hit!(partially_imported);
         if info.is_unstable {
+            if !ctx.cfg.allow_unstable {
+                // the item is unstable and we are not allowed to use unstable items
+                continue;
+            }
             choice.stability = Unstable;
         }
 
@@ -670,6 +674,7 @@ mod tests {
         prefer_prelude: bool,
         prefer_absolute: bool,
         prefer_no_std: bool,
+        allow_unstable: bool,
         expect: Expect,
     ) {
         let (db, pos) = TestDB::with_position(ra_fixture);
@@ -711,7 +716,7 @@ mod tests {
                 module,
                 prefix,
                 ignore_local_imports,
-                ImportPathConfig { prefer_no_std, prefer_prelude, prefer_absolute },
+                ImportPathConfig { prefer_no_std, prefer_prelude, prefer_absolute, allow_unstable },
             );
             format_to!(
                 res,
@@ -732,7 +737,7 @@ mod tests {
         path: &str,
         expect: Expect,
     ) {
-        check_found_path_(ra_fixture, path, false, false, false, expect);
+        check_found_path_(ra_fixture, path, false, false, false, false, expect);
     }
 
     fn check_found_path_prelude(
@@ -740,7 +745,7 @@ mod tests {
         path: &str,
         expect: Expect,
     ) {
-        check_found_path_(ra_fixture, path, true, false, false, expect);
+        check_found_path_(ra_fixture, path, true, false, false, false, expect);
     }
 
     fn check_found_path_absolute(
@@ -748,7 +753,7 @@ mod tests {
         path: &str,
         expect: Expect,
     ) {
-        check_found_path_(ra_fixture, path, false, true, false, expect);
+        check_found_path_(ra_fixture, path, false, true, false, false, expect);
     }
 
     fn check_found_path_prefer_no_std(
@@ -756,7 +761,15 @@ mod tests {
         path: &str,
         expect: Expect,
     ) {
-        check_found_path_(ra_fixture, path, false, false, true, expect);
+        check_found_path_(ra_fixture, path, false, false, true, false, expect);
+    }
+
+    fn check_found_path_prefer_no_std_allow_unstable(
+        #[rust_analyzer::rust_fixture] ra_fixture: &str,
+        path: &str,
+        expect: Expect,
+    ) {
+        check_found_path_(ra_fixture, path, false, false, true, true, expect);
     }
 
     #[test]
@@ -1951,7 +1964,7 @@ pub mod ops {
 
     #[test]
     fn respect_unstable_modules() {
-        check_found_path_prefer_no_std(
+        check_found_path_prefer_no_std_allow_unstable(
             r#"
 //- /main.rs crate:main deps:std,core
 extern crate std;
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 da9ffae8aab..c78818c642c 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
@@ -114,6 +114,9 @@ pub struct ImportPathConfig {
     pub prefer_prelude: bool,
     /// If true, prefer abs path (starting with `::`) where it is available.
     pub prefer_absolute: bool,
+    /// If true, paths containing `#[unstable]` segments may be returned, but only if if there is no
+    /// stable path. This does not check, whether the item itself that is being imported is `#[unstable]`.
+    pub allow_unstable: 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 3545bf76776..d960aaf99f3 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -1159,6 +1159,7 @@ impl HirDisplay for Ty {
                                 prefer_no_std: false,
                                 prefer_prelude: true,
                                 prefer_absolute: false,
+                                allow_unstable: true,
                             },
                         ) {
                             write!(f, "{}", path.display(f.db.upcast(), f.edition()))?;
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 82d8db42589..fb533077d96 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
@@ -28,6 +28,7 @@ impl AssistConfig {
             prefer_no_std: self.prefer_no_std,
             prefer_prelude: self.prefer_prelude,
             prefer_absolute: self.prefer_absolute,
+            allow_unstable: 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 40669c65c57..88f893e42a6 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
@@ -660,7 +660,7 @@ fn enum_variants_with_paths(
         if let Some(path) = ctx.module.find_path(
             ctx.db,
             hir::ModuleDef::from(variant),
-            ctx.config.import_path_config(),
+            ctx.config.import_path_config(ctx.is_nightly),
         ) {
             // Variants with trivial paths are already added by the existing completion logic,
             // so we should avoid adding these twice
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 db18b531d7c..e7101751701 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
@@ -247,7 +247,7 @@ pub(crate) fn complete_expr_path(
                             .find_path(
                                 ctx.db,
                                 hir::ModuleDef::from(strukt),
-                                ctx.config.import_path_config(),
+                                ctx.config.import_path_config(ctx.is_nightly),
                             )
                             .filter(|it| it.len() > 1);
 
@@ -269,7 +269,7 @@ pub(crate) fn complete_expr_path(
                             .find_path(
                                 ctx.db,
                                 hir::ModuleDef::from(un),
-                                ctx.config.import_path_config(),
+                                ctx.config.import_path_config(ctx.is_nightly),
                             )
                             .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 435b88de4ae..24243f57b46 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
@@ -257,7 +257,7 @@ fn import_on_the_fly(
     };
     let user_input_lowercased = potential_import_name.to_lowercase();
 
-    let import_cfg = ctx.config.import_path_config();
+    let import_cfg = ctx.config.import_path_config(ctx.is_nightly);
 
     import_assets
         .search_for_imports(&ctx.sema, import_cfg, ctx.config.insert_use.prefix_kind)
@@ -316,7 +316,7 @@ fn import_on_the_fly_pat_(
         ItemInNs::Values(def) => matches!(def, hir::ModuleDef::Const(_)),
     };
     let user_input_lowercased = potential_import_name.to_lowercase();
-    let cfg = ctx.config.import_path_config();
+    let cfg = ctx.config.import_path_config(ctx.is_nightly);
 
     import_assets
         .search_for_imports(&ctx.sema, cfg, ctx.config.insert_use.prefix_kind)
@@ -358,7 +358,7 @@ fn import_on_the_fly_method(
 
     let user_input_lowercased = potential_import_name.to_lowercase();
 
-    let cfg = ctx.config.import_path_config();
+    let cfg = ctx.config.import_path_config(ctx.is_nightly);
 
     import_assets
         .search_for_imports(&ctx.sema, cfg, ctx.config.insert_use.prefix_kind)
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 67ea05e002b..2c39a8fdfed 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
@@ -60,7 +60,7 @@ pub(crate) fn complete_postfix(
         None => return,
     };
 
-    let cfg = ctx.config.import_path_config();
+    let cfg = ctx.config.import_path_config(ctx.is_nightly);
 
     if let Some(drop_trait) = ctx.famous_defs().core_ops_Drop() {
         if receiver_ty.impls_trait(ctx.db, drop_trait, &[]) {
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 c641df38ff2..45aab38e8ea 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/config.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/config.rs
@@ -59,11 +59,12 @@ impl CompletionConfig<'_> {
             .flat_map(|snip| snip.prefix_triggers.iter().map(move |trigger| (&**trigger, snip)))
     }
 
-    pub fn import_path_config(&self) -> ImportPathConfig {
+    pub fn import_path_config(&self, allow_unstable: bool) -> ImportPathConfig {
         ImportPathConfig {
             prefer_no_std: self.prefer_no_std,
             prefer_prelude: self.prefer_prelude,
             prefer_absolute: self.prefer_absolute,
+            allow_unstable,
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
index 3a2a4a23a19..366e79cddfa 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
@@ -443,7 +443,9 @@ pub(crate) struct CompletionContext<'a> {
     /// The module of the `scope`.
     pub(crate) module: hir::Module,
     /// Whether nightly toolchain is used. Cached since this is looked up a lot.
-    is_nightly: bool,
+    pub(crate) is_nightly: bool,
+    /// The edition of the current crate
+    // FIXME: This should probably be the crate of the current token?
     pub(crate) edition: Edition,
 
     /// The expected name of what we are completing.
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 56d7eeaf8ea..ac6b1207f2e 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
@@ -289,7 +289,7 @@ pub fn resolve_completion_edits(
     let new_ast = scope.clone_for_update();
     let mut import_insert = TextEdit::builder();
 
-    let cfg = config.import_path_config();
+    let cfg = config.import_path_config(true);
 
     imports.into_iter().for_each(|(full_import_path, imported_name)| {
         let items_with_name = items_locator::items_with_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 1b7adf1adb0..dc7eacbfbaf 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
@@ -301,7 +301,7 @@ pub(crate) fn render_expr(
             .unwrap_or_else(|| String::from("..."))
     };
 
-    let cfg = ctx.config.import_path_config();
+    let cfg = ctx.config.import_path_config(ctx.is_nightly);
 
     let label = expr.gen_source_code(&ctx.scope, &mut label_formatter, cfg, ctx.edition).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 04bb178c658..866b83a6146 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs
@@ -164,7 +164,7 @@ impl Snippet {
 }
 
 fn import_edits(ctx: &CompletionContext<'_>, requires: &[ModPath]) -> Option<Vec<LocatedImport>> {
-    let import_cfg = ctx.config.import_path_config();
+    let import_cfg = ctx.config.import_path_config(ctx.is_nightly);
 
     let resolve = |import| {
         let item = ctx.scope.resolve_mod_path(import).next()?;
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 d491e438fef..2e7c53def7f 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
@@ -1391,6 +1391,41 @@ pub struct FooStruct {}
 }
 
 #[test]
+fn flyimport_pattern_unstable_path() {
+    check(
+        r#"
+//- /main.rs crate:main deps:std
+fn function() {
+    let foo$0
+}
+//- /std.rs crate:std
+#[unstable]
+pub mod unstable {
+    pub struct FooStruct {}
+}
+"#,
+        expect![""],
+    );
+    check(
+        r#"
+//- toolchain:nightly
+//- /main.rs crate:main deps:std
+fn function() {
+    let foo$0
+}
+//- /std.rs crate:std
+#[unstable]
+pub mod unstable {
+    pub struct FooStruct {}
+}
+"#,
+        expect![[r#"
+            st FooStruct (use std::unstable::FooStruct)
+        "#]],
+    );
+}
+
+#[test]
 fn flyimport_pattern_unstable_item_on_nightly() {
     check(
         r#"
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 a045c22c2df..f045e44dd31 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
@@ -319,6 +319,7 @@ impl Ctx<'_> {
                                 prefer_no_std: false,
                                 prefer_prelude: true,
                                 prefer_absolute: false,
+                                allow_unstable: true,
                             };
                             let found_path = self.target_module.find_path(
                                 self.source_scope.db.upcast(),
@@ -378,6 +379,7 @@ impl Ctx<'_> {
                     prefer_no_std: false,
                     prefer_prelude: true,
                     prefer_absolute: false,
+                    allow_unstable: true,
                 };
                 let found_path =
                     self.target_module.find_path(self.source_scope.db.upcast(), def, cfg)?;
@@ -417,6 +419,7 @@ impl Ctx<'_> {
                             prefer_no_std: false,
                             prefer_prelude: true,
                             prefer_absolute: false,
+                            allow_unstable: true,
                         };
                         let found_path = self.target_module.find_path(
                             self.source_scope.db.upcast(),
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 dca889d1a8e..f22041ebe23 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
@@ -147,6 +147,7 @@ pub(crate) fn json_in_items(
                             prefer_no_std: config.prefer_no_std,
                             prefer_prelude: config.prefer_prelude,
                             prefer_absolute: config.prefer_absolute,
+                            allow_unstable: true,
                         };
 
                         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 fd1044e51bc..938b7182bc9 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
                                 prefer_no_std: ctx.config.prefer_no_std,
                                 prefer_prelude: ctx.config.prefer_prelude,
                                 prefer_absolute: ctx.config.prefer_absolute,
+                                allow_unstable: ctx.is_nightly,
                             },
                         )?;
 
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 3ad84f7bda2..b023a95fb35 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
@@ -70,6 +70,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Option<Vec<Assist>
                     prefer_no_std: ctx.config.prefer_no_std,
                     prefer_prelude: ctx.config.prefer_prelude,
                     prefer_absolute: ctx.config.prefer_absolute,
+                    allow_unstable: ctx.is_nightly,
                 },
                 ctx.edition,
             )
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 1e99d7ad6e6..50c91a69602 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
@@ -83,7 +83,7 @@ use either::Either;
 use hir::{db::ExpandDatabase, diagnostics::AnyDiagnostic, Crate, HirFileId, InFile, Semantics};
 use ide_db::{
     assists::{Assist, AssistId, AssistKind, AssistResolveStrategy},
-    base_db::SourceDatabase,
+    base_db::{ReleaseChannel, SourceDatabase},
     generated::lints::{Lint, LintGroup, CLIPPY_LINT_GROUPS, DEFAULT_LINTS, DEFAULT_LINT_GROUPS},
     imports::insert_use::InsertUseConfig,
     label::Label,
@@ -276,6 +276,7 @@ struct DiagnosticsContext<'a> {
     sema: Semantics<'a, RootDatabase>,
     resolve: &'a AssistResolveStrategy,
     edition: Edition,
+    is_nightly: bool,
 }
 
 impl DiagnosticsContext<'_> {
@@ -368,7 +369,11 @@ pub fn semantic_diagnostics(
 
     let module = sema.file_to_module_def(file_id);
 
-    let ctx = DiagnosticsContext { config, sema, resolve, edition: file_id.edition() };
+    let is_nightly = matches!(
+        module.and_then(|m| db.toolchain_channel(m.krate().into())),
+        Some(ReleaseChannel::Nightly) | None
+    );
+    let ctx = DiagnosticsContext { config, sema, resolve, edition: file_id.edition(), is_nightly };
 
     let mut diags = Vec::new();
     match module {
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 4edc3633fbe..4bead14e31d 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
+++ b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
@@ -673,6 +673,7 @@ impl Match {
                     prefer_no_std: false,
                     prefer_prelude: true,
                     prefer_absolute: false,
+                    allow_unstable: true,
                 };
                 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 bcaec520195..18c27c84496 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
@@ -465,6 +465,7 @@ impl flags::AnalysisStats {
                                 prefer_no_std: false,
                                 prefer_prelude: true,
                                 prefer_absolute: false,
+                                allow_unstable: true,
                             },
                             Edition::LATEST,
                         )