mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 21:13:37 +00:00
fix: Panic when displaying generic params with defaults, again
This commit is contained in:
parent
e7a4c99ce3
commit
94ec3fe7ed
2 changed files with 50 additions and 2 deletions
|
@ -1053,8 +1053,21 @@ impl HirDisplay for Ty {
|
||||||
generic_args_sans_defaults(f, Some(generic_def_id), parameters);
|
generic_args_sans_defaults(f, Some(generic_def_id), parameters);
|
||||||
assert!(params_len >= parameters.len());
|
assert!(params_len >= parameters.len());
|
||||||
let defaults = params_len - parameters.len();
|
let defaults = params_len - parameters.len();
|
||||||
let without_impl =
|
|
||||||
self_param as usize + type_ + const_ + lifetime - defaults;
|
// Normally, functions cannot have default parameters, but they can,
|
||||||
|
// for function-like things such as struct names or enum variants.
|
||||||
|
// The former cannot have defaults but parents, and the later cannot have
|
||||||
|
// parents but defaults.
|
||||||
|
// So, if `parent_len` > 0, it have a parent and thus it doesn't have any
|
||||||
|
// default. Therefore, we shouldn't subtract defaults because those defaults
|
||||||
|
// are from their parents.
|
||||||
|
// And if `parent_len` == 0, either parents don't exists or they don't have
|
||||||
|
// any defaults. Thus, we can - and should - subtract defaults.
|
||||||
|
let without_impl = if parent_len > 0 {
|
||||||
|
params_len - parent_len - impl_
|
||||||
|
} else {
|
||||||
|
params_len - parent_len - impl_ - defaults
|
||||||
|
};
|
||||||
// parent's params (those from enclosing impl or trait, if any).
|
// parent's params (those from enclosing impl or trait, if any).
|
||||||
let (fn_params, parent_params) = parameters.split_at(without_impl + impl_);
|
let (fn_params, parent_params) = parameters.split_at(without_impl + impl_);
|
||||||
|
|
||||||
|
|
|
@ -9465,4 +9465,39 @@ fn main() {
|
||||||
size = 0, align = 1
|
size = 0, align = 1
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
//- minicore: eq
|
||||||
|
pub struct RandomState;
|
||||||
|
pub struct HashMap<K, V, S = RandomState>(K, V, S);
|
||||||
|
|
||||||
|
impl<K, V> HashMap<K, V, RandomState> {
|
||||||
|
pub fn new() -> HashMap<K, V, RandomState> {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K, V, S> PartialEq for HashMap<K, V, S> {
|
||||||
|
fn eq(&self, other: &HashMap<K, V, S>) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let s$0 = HashMap::<_, u64>::ne;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
*s*
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let s: fn ne<HashMap<{unknown}, u64>>(&HashMap<{unknown}, u64>, &HashMap<{unknown}, u64>) -> bool
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
size = 0, align = 1
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue