mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 04:44:57 +00:00
fix: Type param hover shows correct sized bounds.
This commit is contained in:
parent
9ce3c075ad
commit
dfb15292c2
2 changed files with 165 additions and 10 deletions
|
@ -5,16 +5,19 @@ use hir_def::{
|
|||
type_ref::{TypeBound, TypeRef},
|
||||
AdtId, GenericDefId,
|
||||
};
|
||||
use hir_ty::display::{
|
||||
use hir_ty::{
|
||||
display::{
|
||||
write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError,
|
||||
HirFormatter, SizedByDefault,
|
||||
},
|
||||
Interner, TraitRefExt, WhereClause,
|
||||
};
|
||||
use hir_ty::Interner;
|
||||
use syntax::ast::{self, NameOwner};
|
||||
|
||||
use crate::{
|
||||
Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasVisibility, LifetimeParam,
|
||||
Module, Static, Struct, Trait, TyBuilder, Type, TypeAlias, TypeParam, Union, Variant,
|
||||
Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasCrate, HasVisibility,
|
||||
LifetimeParam, Module, Static, Struct, Trait, TyBuilder, Type, TypeAlias, TypeParam, Union,
|
||||
Variant,
|
||||
};
|
||||
|
||||
impl HirDisplay for Function {
|
||||
|
@ -234,12 +237,24 @@ impl HirDisplay for GenericParam {
|
|||
impl HirDisplay for TypeParam {
|
||||
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
|
||||
write!(f, "{}", self.name(f.db))?;
|
||||
if f.omit_verbose_types() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let bounds = f.db.generic_predicates_for_param(self.id);
|
||||
let substs = TyBuilder::type_params_subst(f.db, self.id.parent);
|
||||
let predicates =
|
||||
bounds.iter().cloned().map(|b| b.substitute(&Interner, &substs)).collect::<Vec<_>>();
|
||||
if !(predicates.is_empty() || f.omit_verbose_types()) {
|
||||
let default_sized = SizedByDefault::Sized { anchor: self.module(f.db).krate().id };
|
||||
let predicates: Vec<_> =
|
||||
bounds.iter().cloned().map(|b| b.substitute(&Interner, &substs)).collect();
|
||||
let krate = self.id.parent.krate(f.db).id;
|
||||
let sized_trait =
|
||||
f.db.lang_item(krate, "sized".into()).and_then(|lang_item| lang_item.as_trait());
|
||||
let has_only_sized_bound = predicates.iter().all(move |pred| match pred.skip_binders() {
|
||||
WhereClause::Implemented(it) => Some(it.hir_trait_id()) == sized_trait,
|
||||
_ => false,
|
||||
});
|
||||
let has_only_not_sized_bound = predicates.is_empty();
|
||||
if !has_only_sized_bound || has_only_not_sized_bound {
|
||||
let default_sized = SizedByDefault::Sized { anchor: krate };
|
||||
write_bounds_like_dyn_trait_with_prefix(":", &predicates, default_sized, f)?;
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -3596,6 +3596,146 @@ impl<T: Trait + ?Sized> Foo<T$0> {}
|
|||
);
|
||||
}
|
||||
|
||||
mod type_param_sized_bounds {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn single_implicit() {
|
||||
check(
|
||||
r#"
|
||||
//- minicore: sized
|
||||
fn foo<T$0>() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
*T*
|
||||
|
||||
```rust
|
||||
T
|
||||
```
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_explicit() {
|
||||
check(
|
||||
r#"
|
||||
//- minicore: sized
|
||||
fn foo<T$0: Sized>() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
*T*
|
||||
|
||||
```rust
|
||||
T
|
||||
```
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_relaxed() {
|
||||
check(
|
||||
r#"
|
||||
//- minicore: sized
|
||||
fn foo<T$0: ?Sized>() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
*T*
|
||||
|
||||
```rust
|
||||
T: ?Sized
|
||||
```
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_implicit() {
|
||||
check(
|
||||
r#"
|
||||
//- minicore: sized
|
||||
trait Trait {}
|
||||
fn foo<T$0: Trait>() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
*T*
|
||||
|
||||
```rust
|
||||
T: Trait
|
||||
```
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_explicit() {
|
||||
check(
|
||||
r#"
|
||||
//- minicore: sized
|
||||
trait Trait {}
|
||||
fn foo<T$0: Trait + Sized>() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
*T*
|
||||
|
||||
```rust
|
||||
T: Trait
|
||||
```
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_relaxed() {
|
||||
check(
|
||||
r#"
|
||||
//- minicore: sized
|
||||
trait Trait {}
|
||||
fn foo<T$0: Trait + ?Sized>() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
*T*
|
||||
|
||||
```rust
|
||||
T: Trait + ?Sized
|
||||
```
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mixed() {
|
||||
check(
|
||||
r#"
|
||||
//- minicore: sized
|
||||
fn foo<T$0: ?Sized + Sized + Sized>() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
*T*
|
||||
|
||||
```rust
|
||||
T
|
||||
```
|
||||
"#]],
|
||||
);
|
||||
check(
|
||||
r#"
|
||||
//- minicore: sized
|
||||
trait Trait {}
|
||||
fn foo<T$0: Sized + ?Sized + Sized + Trait>() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
*T*
|
||||
|
||||
```rust
|
||||
T: Trait
|
||||
```
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hover_const_param() {
|
||||
check(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue