mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 06:41:48 +00:00
fix: Fix panics on GATs involving const generics
This workaround avoids constant crashing of rust analyzer when using GATs with const generics, even when the const generics are only on the `impl` block. The workaround treats GATs as non-existing if either itself or the parent has const generics and removes relevant panicking code-paths.
This commit is contained in:
parent
b6d59f2bb4
commit
ad7a1ed8cc
3 changed files with 39 additions and 9 deletions
|
@ -176,10 +176,16 @@ pub(crate) fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
|
|||
let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def)));
|
||||
if parent_generics.is_some() && matches!(def, GenericDefId::TypeAliasId(_)) {
|
||||
let params = db.generic_params(def);
|
||||
let parent_params = &parent_generics.as_ref().unwrap().params;
|
||||
let has_consts =
|
||||
params.iter().any(|(_, x)| matches!(x, TypeOrConstParamData::ConstParamData(_)));
|
||||
return if has_consts {
|
||||
// XXX: treat const generic associated types as not existing to avoid crashes (#11769)
|
||||
let parent_has_consts =
|
||||
parent_params.iter().any(|(_, x)| matches!(x, TypeOrConstParamData::ConstParamData(_)));
|
||||
return if has_consts || parent_has_consts {
|
||||
// XXX: treat const generic associated types as not existing to avoid crashes
|
||||
// (#11769, #12193)
|
||||
// Note: also crashes when the parent has const generics (also even if the GAT
|
||||
// doesn't use them), see `tests::regression::gat_crash_3` for an example.
|
||||
//
|
||||
// Chalk expects the inner associated type's parameters to come
|
||||
// *before*, not after the trait's generics as we've always done it.
|
||||
|
@ -264,12 +270,8 @@ impl Generics {
|
|||
|
||||
fn find_param(&self, param: TypeOrConstParamId) -> Option<(usize, &TypeOrConstParamData)> {
|
||||
if param.parent == self.def {
|
||||
let (idx, (_local_id, data)) = self
|
||||
.params
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, (idx, _))| *idx == param.local_id)
|
||||
.unwrap();
|
||||
let (idx, (_local_id, data)) =
|
||||
self.params.iter().enumerate().find(|(_, (idx, _))| *idx == param.local_id)?;
|
||||
let parent_len = self.parent_generics().map_or(0, Generics::len);
|
||||
Some((parent_len + idx, data))
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue