diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs index a02ec6f85c..c3c934c468 100644 --- a/crates/hir_ty/src/tests/regression.rs +++ b/crates/hir_ty/src/tests/regression.rs @@ -1471,7 +1471,7 @@ fn regression_11688_3() { } #[test] -fn gat_crash() { +fn gat_crash_1() { cov_mark::check!(ignore_gats); check_no_mismatches( r#" @@ -1489,6 +1489,26 @@ fn test() { ); } +#[test] +fn gat_crash_2() { + check_no_mismatches( + r#" +pub struct InlineStorage {} + +pub struct InlineStorageHandle {} + +pub unsafe trait Storage { + type Handle; + fn create() -> Self::Handle; +} + +unsafe impl Storage for InlineStorage { + type Handle = InlineStorageHandle; +} +"#, + ); +} + #[test] fn cfgd_out_self_param() { cov_mark::check!(cfgd_out_self_param); diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs index 0ffd428cff..bdb7677f5d 100644 --- a/crates/hir_ty/src/utils.rs +++ b/crates/hir_ty/src/utils.rs @@ -176,13 +176,22 @@ pub(super) fn associated_type_by_name_including_super_traits( 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(_)) { - // XXX: treat generic associated types as not existing to avoid crashes (#) - // - // Chalk expects the inner associated type's parameters to come - // *before*, not after the trait's generics as we've always done it. - // Adapting to this requires a larger refactoring - cov_mark::hit!(ignore_gats); - return Generics { def, params: Interned::new(Default::default()), parent_generics }; + let params = db.generic_params(def); + if params + .type_or_consts + .iter() + .any(|(_, x)| matches!(x, TypeOrConstParamData::ConstParamData(_))) + { + // XXX: treat const generic associated types as not existing to avoid crashes (#11769) + // + // Chalk expects the inner associated type's parameters to come + // *before*, not after the trait's generics as we've always done it. + // Adapting to this requires a larger refactoring + cov_mark::hit!(ignore_gats); + return Generics { def, params: Interned::new(Default::default()), parent_generics }; + } else { + return Generics { def, params, parent_generics }; + } } Generics { def, params: db.generic_params(def), parent_generics } }