Skip to content

Commit 42aefa7

Browse files
authored
Merge pull request #18675 from ShoyuVanilla/issue-18664
fix: Panic when displaying generic params with defaults, again
2 parents 3e61459 + 8f004a2 commit 42aefa7

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

src/tools/rust-analyzer/crates/hir-ty/src/display.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,8 +1053,21 @@ impl HirDisplay for Ty {
10531053
generic_args_sans_defaults(f, Some(generic_def_id), parameters);
10541054
assert!(params_len >= parameters.len());
10551055
let defaults = params_len - parameters.len();
1056-
let without_impl =
1057-
self_param as usize + type_ + const_ + lifetime - defaults;
1056+
1057+
// Normally, functions cannot have default parameters, but they can,
1058+
// for function-like things such as struct names or enum variants.
1059+
// The former cannot have defaults but parents, and the later cannot have
1060+
// parents but defaults.
1061+
// So, if `parent_len` > 0, it have a parent and thus it doesn't have any
1062+
// default. Therefore, we shouldn't subtract defaults because those defaults
1063+
// are from their parents.
1064+
// And if `parent_len` == 0, either parents don't exists or they don't have
1065+
// any defaults. Thus, we can - and should - subtract defaults.
1066+
let without_impl = if parent_len > 0 {
1067+
params_len - parent_len - impl_
1068+
} else {
1069+
params_len - parent_len - impl_ - defaults
1070+
};
10581071
// parent's params (those from enclosing impl or trait, if any).
10591072
let (fn_params, parent_params) = parameters.split_at(without_impl + impl_);
10601073

src/tools/rust-analyzer/crates/ide/src/hover/tests.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9465,4 +9465,39 @@ fn main() {
94659465
size = 0, align = 1
94669466
"#]],
94679467
);
9468+
9469+
check(
9470+
r#"
9471+
//- minicore: eq
9472+
pub struct RandomState;
9473+
pub struct HashMap<K, V, S = RandomState>(K, V, S);
9474+
9475+
impl<K, V> HashMap<K, V, RandomState> {
9476+
pub fn new() -> HashMap<K, V, RandomState> {
9477+
loop {}
9478+
}
9479+
}
9480+
9481+
impl<K, V, S> PartialEq for HashMap<K, V, S> {
9482+
fn eq(&self, other: &HashMap<K, V, S>) -> bool {
9483+
false
9484+
}
9485+
}
9486+
9487+
fn main() {
9488+
let s$0 = HashMap::<_, u64>::ne;
9489+
}
9490+
"#,
9491+
expect![[r#"
9492+
*s*
9493+
9494+
```rust
9495+
let s: fn ne<HashMap<{unknown}, u64>>(&HashMap<{unknown}, u64>, &HashMap<{unknown}, u64>) -> bool
9496+
```
9497+
9498+
---
9499+
9500+
size = 0, align = 1
9501+
"#]],
9502+
);
94689503
}

0 commit comments

Comments
 (0)