Skip to content

Commit 3170599

Browse files
bors[bot]iDawer
andauthored
10202: fix: Type param hover shows correct sized bounds. r=flodiebold a=iDawer Closes rust-lang#9949 This adds implicit `: Sized` bound to type parameters at lowering step. Hovering on type parameter does not show it's `: Sized` bound be it set explicitly or implicitly. This is because it doesn't track that the bound was set implicitly. ### Perf ```rust ./target/rust-analyzer-baseline-3dae94bf -q analysis-stats --memory-usage . Database loaded: 4.51s, 311minstr, 110mb (metadata 1.08s, 22minstr, 743kb; build 3.20s, 8730kinstr, -237kb) crates: 38, mods: 770, decls: 17173, fns: 12835 Item Collection: 29.63s, 85ginstr, 372mb exprs: 353460, ??ty: 364 (0%), ?ty: 232 (0%), !ty: 144 Inference: 118.25s, 284ginstr, 601mb Total: 147.88s, 370ginstr, 973mb ./target/rust-analyzer-hover-ty-param-dfb15292 -q analysis-stats --memory-usage . Database loaded: 4.53s, 311minstr, 110mb (metadata 1.10s, 22minstr, 743kb; build 3.20s, 8672kinstr, -189kb) crates: 38, mods: 770, decls: 17173, fns: 12835 Item Collection: 29.59s, 85ginstr, 372mb exprs: 353460, ??ty: 364 (0%), ?ty: 232 (0%), !ty: 144 Inference: 121.69s, 296ginstr, 601mb Total: 151.28s, 382ginstr, 974mb ``` Co-authored-by: Dawer <[email protected]>
2 parents d270679 + 964c7b3 commit 3170599

File tree

3 files changed

+201
-21
lines changed

3 files changed

+201
-21
lines changed

crates/hir/src/display.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,19 @@ use hir_def::{
55
type_ref::{TypeBound, TypeRef},
66
AdtId, GenericDefId,
77
};
8-
use hir_ty::display::{
9-
write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError,
10-
HirFormatter, SizedByDefault,
8+
use hir_ty::{
9+
display::{
10+
write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError,
11+
HirFormatter, SizedByDefault,
12+
},
13+
Interner, TraitRefExt, WhereClause,
1114
};
12-
use hir_ty::Interner;
1315
use syntax::ast::{self, NameOwner};
1416

1517
use crate::{
16-
Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasVisibility, LifetimeParam,
17-
Module, Static, Struct, Trait, TyBuilder, Type, TypeAlias, TypeParam, Union, Variant,
18+
Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasCrate, HasVisibility,
19+
LifetimeParam, Module, Static, Struct, Trait, TyBuilder, Type, TypeAlias, TypeParam, Union,
20+
Variant,
1821
};
1922

2023
impl HirDisplay for Function {
@@ -234,12 +237,24 @@ impl HirDisplay for GenericParam {
234237
impl HirDisplay for TypeParam {
235238
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
236239
write!(f, "{}", self.name(f.db))?;
240+
if f.omit_verbose_types() {
241+
return Ok(());
242+
}
243+
237244
let bounds = f.db.generic_predicates_for_param(self.id);
238245
let substs = TyBuilder::type_params_subst(f.db, self.id.parent);
239-
let predicates =
240-
bounds.iter().cloned().map(|b| b.substitute(&Interner, &substs)).collect::<Vec<_>>();
241-
if !(predicates.is_empty() || f.omit_verbose_types()) {
242-
let default_sized = SizedByDefault::Sized { anchor: self.module(f.db).krate().id };
246+
let predicates: Vec<_> =
247+
bounds.iter().cloned().map(|b| b.substitute(&Interner, &substs)).collect();
248+
let krate = self.id.parent.krate(f.db).id;
249+
let sized_trait =
250+
f.db.lang_item(krate, "sized".into()).and_then(|lang_item| lang_item.as_trait());
251+
let has_only_sized_bound = predicates.iter().all(move |pred| match pred.skip_binders() {
252+
WhereClause::Implemented(it) => Some(it.hir_trait_id()) == sized_trait,
253+
_ => false,
254+
});
255+
let has_only_not_sized_bound = predicates.is_empty();
256+
if !has_only_sized_bound || has_only_not_sized_bound {
257+
let default_sized = SizedByDefault::Sized { anchor: krate };
243258
write_bounds_like_dyn_trait_with_prefix(":", &predicates, default_sized, f)?;
244259
}
245260
Ok(())

crates/hir_ty/src/lower.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@ pub(crate) fn generic_predicates_for_param_query(
10241024
let ctx =
10251025
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
10261026
let generics = generics(db.upcast(), param_id.parent);
1027-
resolver
1027+
let mut predicates: Vec<_> = resolver
10281028
.where_predicates_in_scope()
10291029
// we have to filter out all other predicates *first*, before attempting to lower them
10301030
.filter(|pred| match pred {
@@ -1038,7 +1038,15 @@ pub(crate) fn generic_predicates_for_param_query(
10381038
WherePredicate::Lifetime { .. } => false,
10391039
})
10401040
.flat_map(|pred| ctx.lower_where_predicate(pred, true).map(|p| make_binders(&generics, p)))
1041-
.collect()
1041+
.collect();
1042+
1043+
let subst = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
1044+
let explicitly_unsized_tys = ctx.unsized_types.into_inner();
1045+
let implicitly_sized_predicates =
1046+
implicitly_sized_clauses(db, param_id.parent, &explicitly_unsized_tys, &subst, &resolver)
1047+
.map(|p| make_binders(&generics, crate::wrap_empty_binders(p)));
1048+
predicates.extend(implicitly_sized_predicates);
1049+
predicates.into()
10421050
}
10431051

10441052
pub(crate) fn generic_predicates_for_param_recover(

crates/ide/src/hover.rs

Lines changed: 166 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3564,20 +3564,21 @@ fn foo() {
35643564
r#"
35653565
//- minicore: sized
35663566
struct Foo<T>(T);
3567-
trait Copy {}
3568-
trait Clone {}
3569-
impl<T: Copy + Clone> Foo<T$0> where T: Sized {}
3567+
trait TraitA {}
3568+
trait TraitB {}
3569+
impl<T: TraitA + TraitB> Foo<T$0> where T: Sized {}
35703570
"#,
35713571
expect![[r#"
35723572
*T*
35733573
35743574
```rust
3575-
T: Copy + Clone
3575+
T: TraitA + TraitB
35763576
```
35773577
"#]],
35783578
);
35793579
check(
35803580
r#"
3581+
//- minicore: sized
35813582
struct Foo<T>(T);
35823583
impl<T> Foo<T$0> {}
35833584
"#,
@@ -3592,6 +3593,7 @@ impl<T> Foo<T$0> {}
35923593
// lifetimes bounds arent being tracked yet
35933594
check(
35943595
r#"
3596+
//- minicore: sized
35953597
struct Foo<T>(T);
35963598
impl<T: 'static> Foo<T$0> {}
35973599
"#,
@@ -3606,25 +3608,180 @@ impl<T: 'static> Foo<T$0> {}
36063608
}
36073609

36083610
#[test]
3609-
fn hover_type_param_not_sized() {
3611+
fn hover_type_param_sized_bounds() {
3612+
// implicit `: Sized` bound
36103613
check(
36113614
r#"
36123615
//- minicore: sized
3616+
trait Trait {}
36133617
struct Foo<T>(T);
3614-
trait Copy {}
3615-
trait Clone {}
3616-
impl<T: Copy + Clone> Foo<T$0> where T: ?Sized {}
3618+
impl<T: Trait> Foo<T$0> {}
3619+
"#,
3620+
expect![[r#"
3621+
*T*
3622+
3623+
```rust
3624+
T: Trait
3625+
```
3626+
"#]],
3627+
);
3628+
check(
3629+
r#"
3630+
//- minicore: sized
3631+
trait Trait {}
3632+
struct Foo<T>(T);
3633+
impl<T: Trait + ?Sized> Foo<T$0> {}
36173634
"#,
36183635
expect![[r#"
36193636
*T*
36203637
36213638
```rust
3622-
T: Copy + Clone + ?Sized
3639+
T: Trait + ?Sized
36233640
```
36243641
"#]],
36253642
);
36263643
}
36273644

3645+
mod type_param_sized_bounds {
3646+
use super::*;
3647+
3648+
#[test]
3649+
fn single_implicit() {
3650+
check(
3651+
r#"
3652+
//- minicore: sized
3653+
fn foo<T$0>() {}
3654+
"#,
3655+
expect![[r#"
3656+
*T*
3657+
3658+
```rust
3659+
T
3660+
```
3661+
"#]],
3662+
);
3663+
}
3664+
3665+
#[test]
3666+
fn single_explicit() {
3667+
check(
3668+
r#"
3669+
//- minicore: sized
3670+
fn foo<T$0: Sized>() {}
3671+
"#,
3672+
expect![[r#"
3673+
*T*
3674+
3675+
```rust
3676+
T
3677+
```
3678+
"#]],
3679+
);
3680+
}
3681+
3682+
#[test]
3683+
fn single_relaxed() {
3684+
check(
3685+
r#"
3686+
//- minicore: sized
3687+
fn foo<T$0: ?Sized>() {}
3688+
"#,
3689+
expect![[r#"
3690+
*T*
3691+
3692+
```rust
3693+
T: ?Sized
3694+
```
3695+
"#]],
3696+
);
3697+
}
3698+
3699+
#[test]
3700+
fn multiple_implicit() {
3701+
check(
3702+
r#"
3703+
//- minicore: sized
3704+
trait Trait {}
3705+
fn foo<T$0: Trait>() {}
3706+
"#,
3707+
expect![[r#"
3708+
*T*
3709+
3710+
```rust
3711+
T: Trait
3712+
```
3713+
"#]],
3714+
);
3715+
}
3716+
3717+
#[test]
3718+
fn multiple_explicit() {
3719+
check(
3720+
r#"
3721+
//- minicore: sized
3722+
trait Trait {}
3723+
fn foo<T$0: Trait + Sized>() {}
3724+
"#,
3725+
expect![[r#"
3726+
*T*
3727+
3728+
```rust
3729+
T: Trait
3730+
```
3731+
"#]],
3732+
);
3733+
}
3734+
3735+
#[test]
3736+
fn multiple_relaxed() {
3737+
check(
3738+
r#"
3739+
//- minicore: sized
3740+
trait Trait {}
3741+
fn foo<T$0: Trait + ?Sized>() {}
3742+
"#,
3743+
expect![[r#"
3744+
*T*
3745+
3746+
```rust
3747+
T: Trait + ?Sized
3748+
```
3749+
"#]],
3750+
);
3751+
}
3752+
3753+
#[test]
3754+
fn mixed() {
3755+
check(
3756+
r#"
3757+
//- minicore: sized
3758+
fn foo<T$0: ?Sized + Sized + Sized>() {}
3759+
"#,
3760+
expect![[r#"
3761+
*T*
3762+
3763+
```rust
3764+
T
3765+
```
3766+
"#]],
3767+
);
3768+
check(
3769+
r#"
3770+
//- minicore: sized
3771+
trait Trait {}
3772+
fn foo<T$0: Sized + ?Sized + Sized + Trait>() {}
3773+
"#,
3774+
expect![[r#"
3775+
*T*
3776+
3777+
```rust
3778+
T: Trait
3779+
```
3780+
"#]],
3781+
);
3782+
}
3783+
}
3784+
36283785
#[test]
36293786
fn hover_const_param() {
36303787
check(

0 commit comments

Comments
 (0)