about summary refs log tree commit diff
path: root/src/tools/rust-analyzer/crates
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-12-28 20:31:20 +0100
committerLukas Wirth <lukastw97@gmail.com>2024-12-28 20:31:20 +0100
commitbf27d88616b60a33f568bf19cc689552b0d22218 (patch)
treebb1b76cbf2c084128fb7ab1381f720130c1ed35d /src/tools/rust-analyzer/crates
parente54cf80b983298d19b983a9a378fe96f25daed2a (diff)
downloadrust-bf27d88616b60a33f568bf19cc689552b0d22218.tar.gz
rust-bf27d88616b60a33f568bf19cc689552b0d22218.zip
Show variance of parameters on hover
Diffstat (limited to 'src/tools/rust-analyzer/crates')
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/generics.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lib.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs20
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/render.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/tests.rs36
5 files changed, 69 insertions, 12 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs
index fe7541d2374..abbf2a4f2ef 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs
@@ -26,14 +26,14 @@ use triomphe::Arc;
 
 use crate::{db::HirDatabase, lt_to_placeholder_idx, to_placeholder_idx, Interner, Substitution};
 
-pub(crate) fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
+pub fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
     let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def)));
     let params = db.generic_params(def);
     let has_trait_self_param = params.trait_self_param().is_some();
     Generics { def, params, parent_generics, has_trait_self_param }
 }
 #[derive(Clone, Debug)]
-pub(crate) struct Generics {
+pub struct Generics {
     def: GenericDefId,
     params: Arc<GenericParams>,
     parent_generics: Option<Box<Generics>>,
@@ -153,7 +153,7 @@ impl Generics {
         (parent_len, self_param, type_params, const_params, impl_trait_params, lifetime_params)
     }
 
-    pub(crate) fn type_or_const_param_idx(&self, param: TypeOrConstParamId) -> Option<usize> {
+    pub fn type_or_const_param_idx(&self, param: TypeOrConstParamId) -> Option<usize> {
         self.find_type_or_const_param(param)
     }
 
@@ -174,7 +174,7 @@ impl Generics {
         }
     }
 
-    pub(crate) fn lifetime_idx(&self, lifetime: LifetimeParamId) -> Option<usize> {
+    pub fn lifetime_idx(&self, lifetime: LifetimeParamId) -> Option<usize> {
         self.find_lifetime(lifetime)
     }
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
index 88134f564c0..3c18ea92816 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -24,7 +24,6 @@ extern crate ra_ap_rustc_pattern_analysis as rustc_pattern_analysis;
 mod builder;
 mod chalk_db;
 mod chalk_ext;
-mod generics;
 mod infer;
 mod inhabitedness;
 mod interner;
@@ -39,6 +38,7 @@ pub mod db;
 pub mod diagnostics;
 pub mod display;
 pub mod dyn_compatibility;
+pub mod generics;
 pub mod lang_items;
 pub mod layout;
 pub mod method_resolution;
@@ -89,10 +89,9 @@ pub use infer::{
     PointerCast,
 };
 pub use interner::Interner;
-pub use lower::diagnostics::*;
 pub use lower::{
-    associated_type_shorthand_candidates, ImplTraitLoweringMode, ParamLoweringMode, TyDefId,
-    TyLoweringContext, ValueTyDefId,
+    associated_type_shorthand_candidates, diagnostics::*, ImplTraitLoweringMode, ParamLoweringMode,
+    TyDefId, TyLoweringContext, ValueTyDefId,
 };
 pub use mapping::{
     from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx,
@@ -102,6 +101,7 @@ pub use mapping::{
 pub use method_resolution::check_orphan_rules;
 pub use traits::TraitEnvironment;
 pub use utils::{all_super_traits, direct_super_traits, is_fn_unsafe_to_call};
+pub use variance::Variance;
 
 pub use chalk_ir::{
     cast::Cast,
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index ac8a62ee850..f8af04302f0 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -101,7 +101,6 @@ pub use crate::{
         PathResolution, Semantics, SemanticsImpl, SemanticsScope, TypeInfo, VisibleTraits,
     },
 };
-pub use hir_ty::method_resolution::TyFingerprint;
 
 // Be careful with these re-exports.
 //
@@ -151,8 +150,9 @@ pub use {
         display::{ClosureStyle, HirDisplay, HirDisplayError, HirWrite},
         dyn_compatibility::{DynCompatibilityViolation, MethodViolationCode},
         layout::LayoutError,
+        method_resolution::TyFingerprint,
         mir::{MirEvalError, MirLowerError},
-        CastError, FnAbi, PointerCast, Safety,
+        CastError, FnAbi, PointerCast, Safety, Variance,
     },
     // FIXME: Properly encapsulate mir
     hir_ty::{mir, Interner as ChalkTyInterner},
@@ -3957,6 +3957,22 @@ impl GenericParam {
             GenericParam::LifetimeParam(it) => it.id.parent.into(),
         }
     }
+
+    pub fn variance(self, db: &dyn HirDatabase) -> Option<Variance> {
+        let parent = match self {
+            GenericParam::TypeParam(it) => it.id.parent(),
+            // const parameters are always invariant
+            GenericParam::ConstParam(_) => return None,
+            GenericParam::LifetimeParam(it) => it.id.parent,
+        };
+        let generics = hir_ty::generics::generics(db.upcast(), parent);
+        let index = match self {
+            GenericParam::TypeParam(it) => generics.type_or_const_param_idx(it.id.into())?,
+            GenericParam::ConstParam(_) => return None,
+            GenericParam::LifetimeParam(it) => generics.lifetime_idx(it.id)?,
+        };
+        db.variances_of(parent)?.get(index).copied()
+    }
 }
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
index 119a864eb96..d87c15154e7 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
@@ -594,12 +594,21 @@ pub(super) fn definition(
         _ => None,
     };
 
+    let variance_info = || match def {
+        Definition::GenericParam(it) => it.variance(db).as_ref().map(ToString::to_string),
+        _ => None,
+    };
+
     let mut extra = String::new();
     if hovered_definition {
         if let Some(notable_traits) = render_notable_trait(db, notable_traits, edition) {
             extra.push_str("\n___\n");
             extra.push_str(&notable_traits);
         }
+        if let Some(variance_info) = variance_info() {
+            extra.push_str("\n___\n");
+            extra.push_str(&variance_info);
+        }
         if let Some(layout_info) = layout_info() {
             extra.push_str("\n___\n");
             extra.push_str(&layout_info);
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
index ed8cd64cdbe..fe7f0c79f5b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
@@ -4721,7 +4721,7 @@ fn hover_type_param_sized_bounds() {
 //- minicore: sized
 trait Trait {}
 struct Foo<T>(T);
-impl<T: Trait> Foo<T$0> {}
+impl<T$0: Trait> Foo<T> {}
 "#,
         expect![[r#"
             *T*
@@ -4736,7 +4736,7 @@ impl<T: Trait> Foo<T$0> {}
 //- minicore: sized
 trait Trait {}
 struct Foo<T>(T);
-impl<T: Trait + ?Sized> Foo<T$0> {}
+impl<T$0: Trait + ?Sized> Foo<T> {}
 "#,
         expect![[r#"
             *T*
@@ -4764,6 +4764,10 @@ fn foo<T$0>() {}
                 ```rust
                 T
                 ```
+
+                ---
+
+                invariant
             "#]],
         );
     }
@@ -4781,6 +4785,10 @@ fn foo<T$0: Sized>() {}
                 ```rust
                 T
                 ```
+
+                ---
+
+                invariant
             "#]],
         );
     }
@@ -4798,6 +4806,10 @@ fn foo<T$0: ?Sized>() {}
                 ```rust
                 T: ?Sized
                 ```
+
+                ---
+
+                invariant
             "#]],
         );
     }
@@ -4816,6 +4828,10 @@ fn foo<T$0: Trait>() {}
                 ```rust
                 T: Trait
                 ```
+
+                ---
+
+                invariant
             "#]],
         );
     }
@@ -4834,6 +4850,10 @@ fn foo<T$0: Trait + Sized>() {}
                 ```rust
                 T: Trait
                 ```
+
+                ---
+
+                invariant
             "#]],
         );
     }
@@ -4852,6 +4872,10 @@ fn foo<T$0: Trait + ?Sized>() {}
                 ```rust
                 T: Trait + ?Sized
                 ```
+
+                ---
+
+                invariant
             "#]],
         );
     }
@@ -4869,6 +4893,10 @@ fn foo<T$0: ?Sized + Sized + Sized>() {}
                 ```rust
                 T
                 ```
+
+                ---
+
+                invariant
             "#]],
         );
     }
@@ -4887,6 +4915,10 @@ fn foo<T$0: Sized + ?Sized + Sized + Trait>() {}
                 ```rust
                 T: Trait
                 ```
+
+                ---
+
+                invariant
             "#]],
         );
     }