diff options
-rw-r--r-- | crates/hir/src/code_model.rs | 20 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 2 | ||||
-rw-r--r-- | crates/ide/src/hover.rs | 52 |
3 files changed, 67 insertions, 7 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 62eccf475..a2255508e 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -5,9 +5,7 @@ use arrayvec::ArrayVec; | |||
5 | use base_db::{CrateDisplayName, CrateId, Edition, FileId}; | 5 | use base_db::{CrateDisplayName, CrateId, Edition, FileId}; |
6 | use either::Either; | 6 | use either::Either; |
7 | use hir_def::{ | 7 | use hir_def::{ |
8 | adt::ReprKind, | 8 | adt::{ReprKind, StructKind, VariantData}, |
9 | adt::StructKind, | ||
10 | adt::VariantData, | ||
11 | builtin_type::BuiltinType, | 9 | builtin_type::BuiltinType, |
12 | expr::{BindingAnnotation, LabelId, Pat, PatId}, | 10 | expr::{BindingAnnotation, LabelId, Pat, PatId}, |
13 | import_map, | 11 | import_map, |
@@ -31,7 +29,7 @@ use hir_expand::{ | |||
31 | }; | 29 | }; |
32 | use hir_ty::{ | 30 | use hir_ty::{ |
33 | autoderef, | 31 | autoderef, |
34 | display::{HirDisplayError, HirFormatter}, | 32 | display::{write_bounds_like_dyn_trait, HirDisplayError, HirFormatter}, |
35 | method_resolution, | 33 | method_resolution, |
36 | traits::{FnTrait, Solution, SolutionVariables}, | 34 | traits::{FnTrait, Solution, SolutionVariables}, |
37 | ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, | 35 | ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, |
@@ -1293,6 +1291,20 @@ impl TypeParam { | |||
1293 | } | 1291 | } |
1294 | } | 1292 | } |
1295 | 1293 | ||
1294 | impl HirDisplay for TypeParam { | ||
1295 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
1296 | write!(f, "{}", self.name(f.db))?; | ||
1297 | let bounds = f.db.generic_predicates_for_param(self.id); | ||
1298 | let substs = Substs::type_params(f.db, self.id.parent); | ||
1299 | let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>(); | ||
1300 | if !(predicates.is_empty() || f.omit_verbose_types()) { | ||
1301 | write!(f, ": ")?; | ||
1302 | write_bounds_like_dyn_trait(&predicates, f)?; | ||
1303 | } | ||
1304 | Ok(()) | ||
1305 | } | ||
1306 | } | ||
1307 | |||
1296 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 1308 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
1297 | pub struct LifetimeParam { | 1309 | pub struct LifetimeParam { |
1298 | pub(crate) id: LifetimeParamId, | 1310 | pub(crate) id: LifetimeParamId, |
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 0e827a29e..a54225c18 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -595,7 +595,7 @@ impl HirDisplay for FnSig { | |||
595 | } | 595 | } |
596 | } | 596 | } |
597 | 597 | ||
598 | fn write_bounds_like_dyn_trait( | 598 | pub fn write_bounds_like_dyn_trait( |
599 | predicates: &[GenericPredicate], | 599 | predicates: &[GenericPredicate], |
600 | f: &mut HirFormatter, | 600 | f: &mut HirFormatter, |
601 | ) -> Result<(), HirDisplayError> { | 601 | ) -> Result<(), HirDisplayError> { |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 2737c900f..61439ae53 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -370,8 +370,9 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> { | |||
370 | } | 370 | } |
371 | Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), | 371 | Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), |
372 | Definition::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), | 372 | Definition::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), |
373 | Definition::TypeParam(_) | Definition::ConstParam(_) => { | 373 | Definition::TypeParam(type_param) => Some(Markup::fenced_block(&type_param.display(db))), |
374 | // FIXME: Hover for generic param | 374 | Definition::ConstParam(_) => { |
375 | // FIXME: Hover for generic const param | ||
375 | None | 376 | None |
376 | } | 377 | } |
377 | }; | 378 | }; |
@@ -3257,4 +3258,51 @@ fn foo() { | |||
3257 | "#]], | 3258 | "#]], |
3258 | ); | 3259 | ); |
3259 | } | 3260 | } |
3261 | |||
3262 | #[test] | ||
3263 | fn hover_type_param() { | ||
3264 | check( | ||
3265 | r#" | ||
3266 | struct Foo<T>(T); | ||
3267 | trait Copy {} | ||
3268 | trait Clone {} | ||
3269 | trait Sized {} | ||
3270 | impl<T: Copy + Clone> Foo<T<|>> where T: Sized {} | ||
3271 | "#, | ||
3272 | expect![[r#" | ||
3273 | *T* | ||
3274 | |||
3275 | ```rust | ||
3276 | T: Copy + Clone + Sized | ||
3277 | ``` | ||
3278 | "#]], | ||
3279 | ); | ||
3280 | check( | ||
3281 | r#" | ||
3282 | struct Foo<T>(T); | ||
3283 | impl<T> Foo<T<|>> {} | ||
3284 | "#, | ||
3285 | expect![[r#" | ||
3286 | *T* | ||
3287 | |||
3288 | ```rust | ||
3289 | T | ||
3290 | ``` | ||
3291 | "#]], | ||
3292 | ); | ||
3293 | // lifetimes aren't being substituted yet | ||
3294 | check( | ||
3295 | r#" | ||
3296 | struct Foo<T>(T); | ||
3297 | impl<T: 'static> Foo<T<|>> {} | ||
3298 | "#, | ||
3299 | expect![[r#" | ||
3300 | *T* | ||
3301 | |||
3302 | ```rust | ||
3303 | T: {error} | ||
3304 | ``` | ||
3305 | "#]], | ||
3306 | ); | ||
3307 | } | ||
3260 | } | 3308 | } |