Skip to content

Commit fc41ea1

Browse files
committed
fix panic on GAT
Signed-off-by: Alex Chi <[email protected]>
1 parent 24cf957 commit fc41ea1

File tree

2 files changed

+37
-8
lines changed

2 files changed

+37
-8
lines changed

crates/hir_ty/src/tests/regression.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1471,7 +1471,7 @@ fn regression_11688_3() {
14711471
}
14721472

14731473
#[test]
1474-
fn gat_crash() {
1474+
fn gat_crash_1() {
14751475
cov_mark::check!(ignore_gats);
14761476
check_no_mismatches(
14771477
r#"
@@ -1489,6 +1489,26 @@ fn test<T: Crash>() {
14891489
);
14901490
}
14911491

1492+
#[test]
1493+
fn gat_crash_2() {
1494+
check_no_mismatches(
1495+
r#"
1496+
pub struct InlineStorage {}
1497+
1498+
pub struct InlineStorageHandle<T: ?Sized> {}
1499+
1500+
pub unsafe trait Storage {
1501+
type Handle<T: ?Sized>;
1502+
fn create<T: ?Sized>() -> Self::Handle<T>;
1503+
}
1504+
1505+
unsafe impl Storage for InlineStorage {
1506+
type Handle<T: ?Sized> = InlineStorageHandle<T>;
1507+
}
1508+
"#,
1509+
);
1510+
}
1511+
14921512
#[test]
14931513
fn cfgd_out_self_param() {
14941514
cov_mark::check!(cfgd_out_self_param);

crates/hir_ty/src/utils.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,22 @@ pub(super) fn associated_type_by_name_including_super_traits(
176176
pub(crate) fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
177177
let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def)));
178178
if parent_generics.is_some() && matches!(def, GenericDefId::TypeAliasId(_)) {
179-
// XXX: treat generic associated types as not existing to avoid crashes (#)
180-
//
181-
// Chalk expects the inner associated type's parameters to come
182-
// *before*, not after the trait's generics as we've always done it.
183-
// Adapting to this requires a larger refactoring
184-
cov_mark::hit!(ignore_gats);
185-
return Generics { def, params: Interned::new(Default::default()), parent_generics };
179+
let params = db.generic_params(def);
180+
if params
181+
.type_or_consts
182+
.iter()
183+
.any(|(_, x)| matches!(x, TypeOrConstParamData::ConstParamData(_)))
184+
{
185+
// XXX: treat const generic associated types as not existing to avoid crashes (#11769)
186+
//
187+
// Chalk expects the inner associated type's parameters to come
188+
// *before*, not after the trait's generics as we've always done it.
189+
// Adapting to this requires a larger refactoring
190+
cov_mark::hit!(ignore_gats);
191+
return Generics { def, params: Interned::new(Default::default()), parent_generics };
192+
} else {
193+
Generics { def, params, parent_generics }
194+
}
186195
}
187196
Generics { def, params: db.generic_params(def), parent_generics }
188197
}

0 commit comments

Comments
 (0)