mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +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},
|
type_ref::{TypeBound, TypeRef},
|
||||||
AdtId, GenericDefId,
|
AdtId, GenericDefId,
|
||||||
};
|
};
|
||||||
use hir_ty::display::{
|
use hir_ty::{
|
||||||
|
display::{
|
||||||
write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError,
|
write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError,
|
||||||
HirFormatter, SizedByDefault,
|
HirFormatter, SizedByDefault,
|
||||||
|
},
|
||||||
|
Interner, TraitRefExt, WhereClause,
|
||||||
};
|
};
|
||||||
use hir_ty::Interner;
|
|
||||||
use syntax::ast::{self, NameOwner};
|
use syntax::ast::{self, NameOwner};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasVisibility, LifetimeParam,
|
Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasCrate, HasVisibility,
|
||||||
Module, Static, Struct, Trait, TyBuilder, Type, TypeAlias, TypeParam, Union, Variant,
|
LifetimeParam, Module, Static, Struct, Trait, TyBuilder, Type, TypeAlias, TypeParam, Union,
|
||||||
|
Variant,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl HirDisplay for Function {
|
impl HirDisplay for Function {
|
||||||
|
@ -234,12 +237,24 @@ impl HirDisplay for GenericParam {
|
||||||
impl HirDisplay for TypeParam {
|
impl HirDisplay for TypeParam {
|
||||||
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
|
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
|
||||||
write!(f, "{}", self.name(f.db))?;
|
write!(f, "{}", self.name(f.db))?;
|
||||||
|
if f.omit_verbose_types() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
let bounds = f.db.generic_predicates_for_param(self.id);
|
let bounds = f.db.generic_predicates_for_param(self.id);
|
||||||
let substs = TyBuilder::type_params_subst(f.db, self.id.parent);
|
let substs = TyBuilder::type_params_subst(f.db, self.id.parent);
|
||||||
let predicates =
|
let predicates: Vec<_> =
|
||||||
bounds.iter().cloned().map(|b| b.substitute(&Interner, &substs)).collect::<Vec<_>>();
|
bounds.iter().cloned().map(|b| b.substitute(&Interner, &substs)).collect();
|
||||||
if !(predicates.is_empty() || f.omit_verbose_types()) {
|
let krate = self.id.parent.krate(f.db).id;
|
||||||
let default_sized = SizedByDefault::Sized { anchor: self.module(f.db).krate().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)?;
|
write_bounds_like_dyn_trait_with_prefix(":", &predicates, default_sized, f)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
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]
|
#[test]
|
||||||
fn hover_const_param() {
|
fn hover_const_param() {
|
||||||
check(
|
check(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue