Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/generics.rs8
-rw-r--r--crates/hir-ty/src/lib.rs8
-rw-r--r--crates/hir/src/lib.rs20
-rw-r--r--crates/ide/src/hover/render.rs9
-rw-r--r--crates/ide/src/hover/tests.rs36
5 files changed, 69 insertions, 12 deletions
diff --git a/crates/hir-ty/src/generics.rs b/crates/hir-ty/src/generics.rs
index fe7541d237..abbf2a4f2e 100644
--- a/crates/hir-ty/src/generics.rs
+++ b/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/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs
index 88134f564c..3c18ea9281 100644
--- a/crates/hir-ty/src/lib.rs
+++ b/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/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index ac8a62ee85..f8af04302f 100644
--- a/crates/hir/src/lib.rs
+++ b/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/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs
index 119a864eb9..d87c15154e 100644
--- a/crates/ide/src/hover/render.rs
+++ b/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/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index ed8cd64cdb..fe7f0c79f5 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/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
"#]],
);
}